1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00

cargo fmt

This commit is contained in:
Nirvan Tyagi 2022-02-24 22:45:00 -08:00
parent 30f6f4c697
commit b8a79d4dda
7 changed files with 244 additions and 121 deletions

View file

@ -14,7 +14,7 @@ use crate::proof_system::gm17::{ProofPoints, VerificationKey, GM17};
use crate::proof_system::{Backend, NonUniversalBackend, Proof, SetupKeypair};
use crate::proof_system::{NotBw6_761Field, Scheme};
use ark_bw6_761::BW6_761;
use rand_0_8::{SeedableRng, rngs::StdRng};
use rand_0_8::{rngs::StdRng, SeedableRng};
impl<T: Field + ArkFieldExtensions + NotBw6_761Field> NonUniversalBackend<T, GM17> for Ark {
fn setup<I: IntoIterator<Item = Statement<T>>>(

View file

@ -15,7 +15,7 @@ use crate::proof_system::ark::{parse_g1, parse_g2};
use crate::proof_system::groth16::{ProofPoints, VerificationKey, G16};
use crate::proof_system::Scheme;
use ark_bw6_761::BW6_761;
use rand_0_8::{SeedableRng, rngs::StdRng};
use rand_0_8::{rngs::StdRng, SeedableRng};
const G16_WARNING: &str = "WARNING: You are using the G16 scheme which is subject to malleability. See zokrates.github.io/toolbox/proving_schemes.html#g16-malleability for implications.";

View file

@ -1,14 +1,13 @@
use ark_marlin::{
ahp::indexer::IndexInfo, ahp::prover::ProverMsg, IndexProverKey, IndexVerifierKey,
Proof as ArkProof,
rng::FiatShamirRng,
ahp::indexer::IndexInfo, ahp::prover::ProverMsg, rng::FiatShamirRng, IndexProverKey,
IndexVerifierKey, Proof as ArkProof,
};
use ark_marlin::Marlin as ArkMarlin;
use ark_ff::{FftField, ToBytes, FromBytes, to_bytes};
use ark_ec::PairingEngine;
use ark_poly::{univariate::DensePolynomial, GeneralEvaluationDomain, EvaluationDomain};
use ark_ff::{to_bytes, FftField, FromBytes, ToBytes};
use ark_poly::{univariate::DensePolynomial, EvaluationDomain, GeneralEvaluationDomain};
use ark_poly_commit::{
data_structures::BatchLCProof,
kzg10::Commitment as KZG10Commitment,
@ -17,14 +16,11 @@ use ark_poly_commit::{
marlin_pc::{Commitment, MarlinKZG10, VerifierKey},
};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use sha3::Keccak256;
use rand_0_8::{SeedableRng, RngCore, Error};
use num::Zero;
use digest::Digest;
use std::{
marker::PhantomData,
convert::TryFrom,
};
use num::Zero;
use rand_0_8::{Error, RngCore, SeedableRng};
use sha3::Keccak256;
use std::{convert::TryFrom, marker::PhantomData};
use zokrates_field::{ArkFieldExtensions, Field};
@ -67,10 +63,12 @@ impl<D: Digest> RngCore for HashFiatShamirRng<D> {
let mut h = D::digest(&seed_ctr).to_vec();
h.reverse(); // Switch to big endian representation for solidity translation
let len = dest.len();
if i*bytes_per_hash + bytes_per_hash >= len {
dest[i * bytes_per_hash..].copy_from_slice(&h.as_slice()[..len - i*bytes_per_hash]);
if i * bytes_per_hash + bytes_per_hash >= len {
dest[i * bytes_per_hash..]
.copy_from_slice(&h.as_slice()[..len - i * bytes_per_hash]);
} else {
dest[i * bytes_per_hash..i * bytes_per_hash + bytes_per_hash].copy_from_slice(h.as_slice());
dest[i * bytes_per_hash..i * bytes_per_hash + bytes_per_hash]
.copy_from_slice(h.as_slice());
}
self.ctr += 1;
seed_ctr.truncate(seed_ctr.len() - 4);
@ -85,7 +83,9 @@ impl<D: Digest> RngCore for HashFiatShamirRng<D> {
impl<D: Digest> FiatShamirRng for HashFiatShamirRng<D> {
fn initialize<'a, T: 'a + ToBytes>(initial_input: &'a T) -> Self {
let mut bytes = Vec::new();
initial_input.write(&mut bytes).expect("failed to convert to bytes");
initial_input
.write(&mut bytes)
.expect("failed to convert to bytes");
let seed = FromBytes::read(D::digest(&bytes).as_ref()).expect("failed to get [u8; 32]");
Self {
seed: seed,
@ -96,23 +96,34 @@ impl<D: Digest> FiatShamirRng for HashFiatShamirRng<D> {
fn absorb<'a, T: 'a + ToBytes>(&mut self, new_input: &'a T) {
let mut bytes = Vec::new();
new_input.write(&mut bytes).expect("failed to convert to bytes");
new_input
.write(&mut bytes)
.expect("failed to convert to bytes");
bytes.extend_from_slice(&self.seed);
self.seed = FromBytes::read(D::digest(&bytes).as_ref()).expect("failed to get [u8; 32]");
self.ctr = 0;
}
}
type PCInst<T> = MarlinKZG10<<T as ArkFieldExtensions>::ArkEngine, DensePolynomial<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>>;
type MarlinInst<T> = ArkMarlin<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr, PCInst<T>, HashFiatShamirRng<Keccak256>>;
type PCInst<T> = MarlinKZG10<
<T as ArkFieldExtensions>::ArkEngine,
DensePolynomial<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>,
>;
type MarlinInst<T> = ArkMarlin<
<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr,
PCInst<T>,
HashFiatShamirRng<Keccak256>,
>;
impl<T: Field + ArkFieldExtensions> UniversalBackend<T, marlin::Marlin> for Ark {
fn universal_setup(size: u32) -> Vec<u8> {
let rng = &mut rand_0_8::rngs::StdRng::from_entropy();
let srs = MarlinInst::<T>::universal_setup(
2usize.pow(size), 2usize.pow(size), 2usize.pow(size), rng
2usize.pow(size),
2usize.pow(size),
2usize.pow(size),
rng,
)
.unwrap();
@ -155,7 +166,11 @@ impl<T: Field + ArkFieldExtensions> UniversalBackend<T, marlin::Marlin> for Ark
// Precompute some useful values for solidity contract
let fs_seed = to_bytes![&MarlinInst::<T>::PROTOCOL_NAME, &vk].unwrap();
let x_root_of_unity = <<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr::get_root_of_unity(usize::try_from(vk.index_info.num_instance_variables).unwrap()).unwrap();
let x_root_of_unity =
<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr::get_root_of_unity(
usize::try_from(vk.index_info.num_instance_variables).unwrap(),
)
.unwrap();
Ok(SetupKeypair::new(
VerificationKey {
@ -211,19 +226,18 @@ impl<T: Field + ArkFieldExtensions> Backend<T, marlin::Marlin> for Ark {
.unwrap();
let mut public_inputs = computation.public_inputs_values();
let domain_x = GeneralEvaluationDomain::<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>::new(public_inputs.len() + 1).unwrap();
let domain_x = GeneralEvaluationDomain::<
<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr,
>::new(public_inputs.len() + 1)
.unwrap();
public_inputs.resize(
core::cmp::max(public_inputs.len(), domain_x.size() - 1),
<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>::zero(),
);
let inputs = public_inputs
.iter()
.map(parse_fr::<T>)
.collect::<Vec<_>>();
let inputs = public_inputs.iter().map(parse_fr::<T>).collect::<Vec<_>>();
let proof = MarlinInst::<T>::prove(&pk, computation, rng)
.unwrap();
let proof = MarlinInst::<T>::prove(&pk, computation, rng).unwrap();
let mut serialized_proof: Vec<u8> = Vec::new();
proof.serialize_uncompressed(&mut serialized_proof).unwrap();
@ -366,8 +380,7 @@ impl<T: Field + ArkFieldExtensions> Backend<T, marlin::Marlin> for Ark {
let rng = &mut rand_0_8::rngs::StdRng::from_entropy();
MarlinInst::<T>::verify(&vk, &inputs, &proof, rng)
.unwrap()
MarlinInst::<T>::verify(&vk, &inputs, &proof, rng).unwrap()
}
}

View file

@ -1,6 +1,8 @@
use crate::proof_system::scheme::{Scheme, UniversalScheme};
use crate::proof_system::{G1Affine, G2Affine, Fr, NotBw6_761Field};
use crate::proof_system::solidity::{SolidityCompatibleScheme, SolidityCompatibleField, solidity_pairing_lib};
use crate::proof_system::solidity::{
solidity_pairing_lib, SolidityCompatibleField, SolidityCompatibleScheme,
};
use crate::proof_system::{Fr, G1Affine, G2Affine, NotBw6_761Field};
use serde::{Deserialize, Serialize};
use zokrates_field::Field;
@ -61,11 +63,18 @@ impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> f
// Replace public parameters in template
let src = template
.replace("<%vk_index_comms_length%>", &vk.index_comms.len().to_string())
.replace(
"<%vk_index_comms_length%>",
&vk.index_comms.len().to_string(),
)
.replace("<%vk_populate_index_comms%>", &{
let mut populate_index_comms = String::new();
for (i, (g, _)) in vk.index_comms.iter().enumerate() {
populate_index_comms.push_str(&format!("vk.index_comms[{}] = Pairing.G1Point({});", i, &g.to_string()));
populate_index_comms.push_str(&format!(
"vk.index_comms[{}] = Pairing.G1Point({});",
i,
&g.to_string()
));
if i < vk.index_comms.len() - 1 {
populate_index_comms.push_str("\n ");
}
@ -76,14 +85,29 @@ impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> f
.replace("<%vk_kzg_gamma_g%>", &vk.vk.gamma_g.to_string())
.replace("<%vk_kzg_h%>", &vk.vk.h.to_string())
.replace("<%vk_kzg_beta_h%>", &vk.vk.beta_h.to_string())
.replace("<%vk_degree_bounds_length%>", &vk.degree_bounds_and_shift_powers.as_ref().unwrap().len().to_string())
.replace(
"<%vk_degree_bounds_length%>",
&vk.degree_bounds_and_shift_powers
.as_ref()
.unwrap()
.len()
.to_string(),
)
.replace("<%vk_g1_shift%>", &{
let h_domain_size = if vk.num_constraints.is_power_of_two() {
vk.num_constraints
} else {
vk.num_constraints.next_power_of_two()
};
vk.degree_bounds_and_shift_powers.as_ref().unwrap().iter().filter(|(b, _)| *b == h_domain_size - 2).next().unwrap().1.to_string()
vk.degree_bounds_and_shift_powers
.as_ref()
.unwrap()
.iter()
.filter(|(b, _)| *b == h_domain_size - 2)
.next()
.unwrap()
.1
.to_string()
})
.replace("<%vk_g2_shift%>", &{
let k_domain_size = if vk.num_non_zero.is_power_of_two() {
@ -91,19 +115,29 @@ impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> f
} else {
vk.num_non_zero.next_power_of_two()
};
vk.degree_bounds_and_shift_powers.as_ref().unwrap().iter().filter(|(b, _)| *b == k_domain_size - 2).next().unwrap().1.to_string()
vk.degree_bounds_and_shift_powers
.as_ref()
.unwrap()
.iter()
.filter(|(b, _)| *b == k_domain_size - 2)
.next()
.unwrap()
.1
.to_string()
})
.replace("<%fs_init_seed_len%>", &(vk.fs_seed.len() / 32).to_string())
.replace("<%fs_init_seed_overflow_len%>", &{
let seed_len_in_32_byte_words = vk.fs_seed.len() / 32;
let seed_len_overflow_in_bytes = vk.fs_seed.len() - (seed_len_in_32_byte_words * 32);
let seed_len_overflow_in_bytes =
vk.fs_seed.len() - (seed_len_in_32_byte_words * 32);
seed_len_overflow_in_bytes.to_string()
})
.replace("<%fs_populate_init_seed%>", &{
let mut populate_init_seed = String::new();
for i in 0..vk.fs_seed.len() / 32 {
let word_32_bytes = hex::encode(&vk.fs_seed[i*32..i*32 + 32]);
populate_init_seed.push_str(&format!("init_seed[{}] = 0x{};", i, &word_32_bytes));
let word_32_bytes = hex::encode(&vk.fs_seed[i * 32..i * 32 + 32]);
populate_init_seed
.push_str(&format!("init_seed[{}] = 0x{};", i, &word_32_bytes));
if i < vk.fs_seed.len() / 32 - 1 {
populate_init_seed.push_str("\n ");
}
@ -112,7 +146,10 @@ impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> f
})
.replace("<%fs_init_seed_overflow%>", &{
let seed_len_in_32_byte_words = vk.fs_seed.len() / 32;
format!("0x{}", hex::encode(&vk.fs_seed[seed_len_in_32_byte_words * 32..]))
format!(
"0x{}",
hex::encode(&vk.fs_seed[seed_len_in_32_byte_words * 32..])
)
})
.replace("<%h_domain_size%>", &{
let size = if vk.num_constraints.is_power_of_two() {
@ -140,15 +177,17 @@ impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> f
size.to_string()
})
.replace("<%x_root%>", &vk.x_root_of_unity.to_string())
.replace("<%f_mod%>", "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001")
.replace("<%f_r%>", "0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb")
.replace(
"<%f_mod%>",
"0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001",
)
.replace(
"<%f_r%>",
"0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb",
)
.replace("<%f_inv%>", "0xc2e1f593efffffff");
format!(
"{}{}",
solidity_pairing_lib, src
)
format!("{}{}", solidity_pairing_lib, src)
}
}
@ -591,28 +630,26 @@ contract Verifier {
mod tests {
use crate::flat_absy::{FlatParameter, FlatVariable};
use crate::ir::{Interpreter, Prog, QuadComb, Statement};
use crate::proof_system::{UniversalBackend, Backend, Proof, Fr};
use crate::proof_system::ark::{Ark, parse_fr};
use crate::proof_system::ark::{parse_fr, Ark};
use crate::proof_system::{Backend, Fr, Proof, UniversalBackend};
use zokrates_field::ArkFieldExtensions;
use super::*;
use zokrates_field::{Bn128Field};
use zokrates_solidity_test::{
contract::Contract,
evm::Evm,
address::Address,
to_be_bytes,
};
use rand_0_8::{rngs::StdRng, SeedableRng};
use ethabi::{Token};
use ethabi::Token;
use primitive_types::U256;
use rand_0_8::{rngs::StdRng, SeedableRng};
use zokrates_field::Bn128Field;
use zokrates_solidity_test::{address::Address, contract::Contract, evm::Evm, to_be_bytes};
/// Helper methods for parsing group structure
pub fn encode_g1_element(g: &G1Affine) -> Token {
Token::Tuple(vec![
Token::Uint(U256::from(&hex::decode(&g.0.trim_start_matches("0x")).unwrap()[..])),
Token::Uint(U256::from(&hex::decode(&g.1.trim_start_matches("0x")).unwrap()[..])),
Token::Uint(U256::from(
&hex::decode(&g.0.trim_start_matches("0x")).unwrap()[..],
)),
Token::Uint(U256::from(
&hex::decode(&g.1.trim_start_matches("0x")).unwrap()[..],
)),
])
}
@ -630,38 +667,66 @@ mod tests {
//}
pub fn encode_fr_element(f: &Fr) -> Token {
Token::Uint(U256::from(&hex::decode(&f.trim_start_matches("0x")).unwrap()[..]))
Token::Uint(U256::from(
&hex::decode(&f.trim_start_matches("0x")).unwrap()[..],
))
}
fn encode_verify_input(proof: Proof<<Marlin as Scheme<Bn128Field>>::ProofPoints>,) -> Vec<Token> {
let input = Token::Array(proof.inputs.iter().map(|s| {
let bytes = hex::decode(s.trim_start_matches("0x")).unwrap();
debug_assert_eq!(bytes.len(), 32);
Token::Uint(U256::from(&bytes[..]))
}).collect::<Vec<_>>());
fn encode_verify_input(
proof: Proof<<Marlin as Scheme<Bn128Field>>::ProofPoints>,
) -> Vec<Token> {
let input = Token::Array(
proof
.inputs
.iter()
.map(|s| {
let bytes = hex::decode(s.trim_start_matches("0x")).unwrap();
debug_assert_eq!(bytes.len(), 32);
Token::Uint(U256::from(&bytes[..]))
})
.collect::<Vec<_>>(),
);
let comms_1_token = Token::Array(proof.proof.commitments[0].iter().map(|(c, _)|{
encode_g1_element(c)
}).collect::<Vec<_>>());
let comms_1_token = Token::Array(
proof.proof.commitments[0]
.iter()
.map(|(c, _)| encode_g1_element(c))
.collect::<Vec<_>>(),
);
let comms_2_token = Token::Array(proof.proof.commitments[1].iter().map(|(c, _)|{
encode_g1_element(c)
}).collect::<Vec<_>>());
let comms_2_token = Token::Array(
proof.proof.commitments[1]
.iter()
.map(|(c, _)| encode_g1_element(c))
.collect::<Vec<_>>(),
);
let degree_bound_comms_2_g1_token = encode_g1_element(proof.proof.commitments[1][1].1.as_ref().unwrap());
let degree_bound_comms_2_g1_token =
encode_g1_element(proof.proof.commitments[1][1].1.as_ref().unwrap());
let comms_3_token = Token::Array(proof.proof.commitments[2].iter().map(|(c, _)|{
encode_g1_element(c)
}).collect::<Vec<_>>());
let comms_3_token = Token::Array(
proof.proof.commitments[2]
.iter()
.map(|(c, _)| encode_g1_element(c))
.collect::<Vec<_>>(),
);
let degree_bound_comms_3_g2_token = encode_g1_element(proof.proof.commitments[2][0].1.as_ref().unwrap());
let degree_bound_comms_3_g2_token =
encode_g1_element(proof.proof.commitments[2][0].1.as_ref().unwrap());
let evals_token = Token::Array(proof.proof.evaluations.into_iter().map(|f| {
encode_fr_element(&parse_fr::<Bn128Field>(&Bn128Field::into_ark(f)))
}).collect::<Vec<_>>());
let evals_token = Token::Array(
proof
.proof
.evaluations
.into_iter()
.map(|f| encode_fr_element(&parse_fr::<Bn128Field>(&Bn128Field::into_ark(f))))
.collect::<Vec<_>>(),
);
let pc_lc_opening_1_token = encode_g1_element(&proof.proof.pc_proof_proof[0].0);
let degree_bound_pc_lc_opening_1_token = encode_fr_element(&parse_fr::<Bn128Field>(&Bn128Field::into_ark(proof.proof.pc_proof_proof[0].1.clone().unwrap())));
let degree_bound_pc_lc_opening_1_token = encode_fr_element(&parse_fr::<Bn128Field>(
&Bn128Field::into_ark(proof.proof.pc_proof_proof[0].1.clone().unwrap()),
));
let pc_lc_opening_2_token = encode_g1_element(&proof.proof.pc_proof_proof[1].0);
let proof_tokens = vec![
@ -715,7 +780,8 @@ mod tests {
//let ans = <Ark as Backend<Bn128Field, Marlin>>::verify(keypair.vk, proof);
//assert!(ans);
let mut src = <Marlin as SolidityCompatibleScheme<Bn128Field>>::export_solidity_verifier(keypair.vk);
let mut src =
<Marlin as SolidityCompatibleScheme<Bn128Field>>::export_solidity_verifier(keypair.vk);
src = src.replace("\"", "\\\"");
let solc_config = r#"
@ -734,8 +800,8 @@ mod tests {
"": [ "*" ] } }
}
}"#
.replace("<%opt%>", &true.to_string())
.replace("<%src%>", &src);
.replace("<%opt%>", &true.to_string())
.replace("<%src%>", &src);
let contract = Contract::compile_from_config(&solc_config, "Verifier").unwrap();
@ -746,14 +812,26 @@ mod tests {
evm.create_account(&deployer, 0);
// Deploy contract
let create_result = evm.deploy(contract.encode_create_contract_bytes(&[]).unwrap(), &deployer).unwrap();
let create_result = evm
.deploy(
contract.encode_create_contract_bytes(&[]).unwrap(),
&deployer,
)
.unwrap();
let contract_addr = create_result.addr.clone();
//println!("Contract deploy gas cost: {}", create_result.gas);
// Call verify function on contract
let result = evm.call(contract.encode_call_contract_bytes("verify", &encode_verify_input(proof)).unwrap(), &contract_addr, &deployer).unwrap();
let result = evm
.call(
contract
.encode_call_contract_bytes("verify", &encode_verify_input(proof))
.unwrap(),
&contract_addr,
&deployer,
)
.unwrap();
assert_eq!(&result.out, &to_be_bytes(&U256::from(1)));
//println!("{:?}", result);
}
}

View file

@ -61,10 +61,7 @@ impl Contract {
Self::compile_from_config(&solc_config, contract_name)
}
pub fn compile_from_config(
config: &String,
contract_name: &str,
) -> Result<Self, Error> {
pub fn compile_from_config(config: &String, contract_name: &str) -> Result<Self, Error> {
// Compile source file using solc
// Configuration: https://docs.soliditylang.org/en/v0.8.10/using-the-compiler.html
let out = from_str::<serde_json::Value>(&compile(config))
@ -104,7 +101,7 @@ impl Contract {
.to_string()
.as_bytes(),
)
.map_err(|_| Box::new(EvmTestError("ethabi failed loading abi".to_string())))?;
.map_err(|_| Box::new(EvmTestError("ethabi failed loading abi".to_string())))?;
abi
};
@ -122,26 +119,30 @@ impl Contract {
))
})?;
Ok(binary.to_vec())
},
}
None => Ok(self.binary.clone()),
}
}
pub fn encode_call_contract_bytes(&self, fn_name: &str, input: &[Token]) -> Result<Vec<u8>, Error> {
pub fn encode_call_contract_bytes(
&self,
fn_name: &str,
input: &[Token],
) -> Result<Vec<u8>, Error> {
match self.abi.functions.get(fn_name) {
Some(f) => {
//let c = f[0].inputs.iter().map(|p| p.kind.clone()).collect::<Vec<_>>();
//println!("{:?}", c);
let call_binary = f[0].encode_input(input)
.map_err(|_| {
Box::new(EvmTestError(
"abi function failed to encode inputs".to_string(),
))
})?;
let call_binary = f[0].encode_input(input).map_err(|_| {
Box::new(EvmTestError(
"abi function failed to encode inputs".to_string(),
))
})?;
Ok(call_binary.to_vec())
},
None => Err(Box::new(EvmTestError("abi does not include function".to_string()))),
}
None => Err(Box::new(EvmTestError(
"abi does not include function".to_string(),
))),
}
}
}

View file

@ -28,14 +28,21 @@ impl Evm {
Self { vm }
}
pub fn call(&mut self, input: Vec<u8>, addr: &Address, caller: &Address) -> Result<CallResult, Error> {
pub fn call(
&mut self,
input: Vec<u8>,
addr: &Address,
caller: &Address,
) -> Result<CallResult, Error> {
self.vm.env.tx.caller = caller.as_ref().clone();
self.vm.env.tx.transact_to = TransactTo::Call(addr.as_ref().clone());
self.vm.env.tx.data = input.into();
let (op_out, tx_out, gas, log_out) = self.vm.transact_commit();
let out = match tx_out {
TransactOut::Call(out) => Ok(out.to_vec()),
_ => Err(Box::new(EvmTestError("call contract function failed".to_string()))),
_ => Err(Box::new(EvmTestError(
"call contract function failed".to_string(),
))),
}?;
Ok(CallResult {
op_out,

View file

@ -35,13 +35,9 @@ pub fn to_be_bytes(n: &U256) -> [u8; 32] {
#[cfg(test)]
mod tests {
use super::*;
use crate::{
address::Address,
contract::Contract,
evm::{Evm},
};
use rand::{rngs::StdRng, SeedableRng};
use crate::{address::Address, contract::Contract, evm::Evm};
use ethabi::Token;
use rand::{rngs::StdRng, SeedableRng};
#[test]
fn simple_storage_contract_test() {
@ -61,21 +57,49 @@ mod tests {
evm.create_account(&deployer, 0);
// Deploy contract
let create_result = evm.deploy(contract.encode_create_contract_bytes(&[]).unwrap(), &deployer).unwrap();
let create_result = evm
.deploy(
contract.encode_create_contract_bytes(&[]).unwrap(),
&deployer,
)
.unwrap();
let contract_addr = create_result.addr.clone();
println!("Contract deploy gas cost: {}", create_result.gas);
// Call get function on contract
let get_result = evm.call(contract.encode_call_contract_bytes("get", &[]).unwrap(), &contract_addr, &deployer).unwrap();
let get_result = evm
.call(
contract.encode_call_contract_bytes("get", &[]).unwrap(),
&contract_addr,
&deployer,
)
.unwrap();
assert_eq!(&get_result.out, &to_be_bytes(&U256::from(0)));
println!("{:?}", get_result);
// Call set function on contract
let set_result = evm.call(contract.encode_call_contract_bytes("set", &[Token::Tuple(vec![Token::Uint(U256::from(40))])]).unwrap(), &contract_addr, &deployer).unwrap();
let set_result = evm
.call(
contract
.encode_call_contract_bytes(
"set",
&[Token::Tuple(vec![Token::Uint(U256::from(40))])],
)
.unwrap(),
&contract_addr,
&deployer,
)
.unwrap();
println!("{:?}", set_result);
// Call get function on contract
let get_result = evm.call(contract.encode_call_contract_bytes("get", &[]).unwrap(), &contract_addr, &deployer).unwrap();
let get_result = evm
.call(
contract.encode_call_contract_bytes("get", &[]).unwrap(),
&contract_addr,
&deployer,
)
.unwrap();
assert_eq!(&get_result.out, &to_be_bytes(&U256::from(40)));
println!("{:?}", get_result);
}