how to use pallet_revive to execute solidity #254
-
I want to fuzz the revive compiler, but I don't know how to efficiently execute the bytecode generated by revive. Could you please let me know if there's a demo I can learn from? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 18 replies
-
fn instantiate_works() {
use specs::SpecsAction::*;
let specs = Specs {
differential: false,
balances: vec![(ALICE, 1_000_000_000)],
actions: vec![Instantiate {
origin: TestAddress::Alice,
value: 0,
gas_limit: Some(GAS_LIMIT),
storage_deposit_limit: Some(DEPOSIT_LIMIT),
code: Code::Bytes(include_bytes!("../fixtures/Baseline.pvm").to_vec()),
data: vec![],
salt: OptionalHex::default(),
}],
};
specs.run();
} The demo provides a test program for the PVM file, but I don't know how to specify the function and parameters to call. I assume it should be set in the data, but I'm not sure how to implement it. |
Beta Was this translation helpful? Give feedback.
-
main.rs, which is modified from demo fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 3 {
eprintln!("Usage: <program> <contract_path> <data_string>");
std::process::exit(1);
}
let contract_path = &args[1];
let data_string = &args[2];
let mut contract_code = Vec::new();
let mut contract_file = File::open(contract_path).expect("Failed to open contract file");
contract_file
.read_to_end(&mut contract_code)
.expect("Failed to read contract file");
let data = data_string.as_bytes().to_vec();
let specs = Specs {
differential: false,
balances: vec![(ALICE, 1_000_000_000)],
actions: vec![Instantiate {
origin: TestAddress::Alice,
value: 0,
gas_limit: Some(GAS_LIMIT),
storage_deposit_limit: Some(DEPOSIT_LIMIT),
code: Code::Bytes(contract_code),
data: data,
salt: OptionalHex::default(),
}],
};
// 运行 specs
let results = specs.run();
// 打印返回的 CallResult 向量
for result in results {
println!("{:?}", result);
}
} test.sol contract C {
int a=0;
constructor() {
h();
}
function h() public returns(int){
a=1123456789;
return a;
}
}
b8c9d365 is the selector of function h. The following output indicates that the function's output is empty. However, the function's output should be 1123456789. I don't know why.
|
Beta Was this translation helpful? Give feedback.
-
pub fn run(self) -> Vec<CallResult> {
if self.differential {
#[cfg(not(feature = "solidity"))]
panic!("{NO_SOLIDITY_FRONTEND}");
#[cfg(feature = "solidity")]
self.run_on_evm()
} else {
self
}
.run_on_pallet()
} May I ask what the difference is between run_on_evm and run_on_pallet? It seems that both are executed within PolkaVM, is that correct? |
Beta Was this translation helpful? Give feedback.
Hi @Subway2023, the
data
field is indeed what gets passed to the contract as input ("call data" in Solidity terms). The function being called is implied by the first 4 bytes in the call data (so called function selector). For call data encoding I suggest using the alloy crate, it has even some convenience macros.Edit for completeness:
Instantiate
will always run the constructor code.