Support conatrcts call args in rhai bindings
Some checks failed
Rhai Tests / Run Rhai Tests (push) Has been cancelled
Some checks failed
Rhai Tests / Run Rhai Tests (push) Has been cancelled
This commit is contained in:
@@ -9,10 +9,10 @@ use std::sync::Mutex;
|
||||
use once_cell::sync::Lazy;
|
||||
use tokio::runtime::Runtime;
|
||||
use ethers::types::{Address, U256};
|
||||
use ethers::abi::Token;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::hero_vault::{keypair, symmetric, ethereum};
|
||||
use crate::hero_vault::ethereum::{prepare_function_arguments, convert_token_to_rhai};
|
||||
|
||||
// Global Tokio runtime for blocking async operations
|
||||
static RUNTIME: Lazy<Mutex<Runtime>> = Lazy::new(|| {
|
||||
@@ -750,8 +750,15 @@ fn load_contract_abi_from_file(network_name: &str, address: &str, file_path: &st
|
||||
}
|
||||
}
|
||||
|
||||
// Call a read-only function on a contract
|
||||
fn call_contract_read(contract_json: &str, function_name: &str) -> Dynamic {
|
||||
// Use the utility functions from the ethereum module
|
||||
|
||||
// Call a read-only function on a contract (no arguments version)
|
||||
fn call_contract_read_no_args(contract_json: &str, function_name: &str) -> Dynamic {
|
||||
call_contract_read(contract_json, function_name, rhai::Array::new())
|
||||
}
|
||||
|
||||
// Call a read-only function on a contract with arguments
|
||||
fn call_contract_read(contract_json: &str, function_name: &str, args: rhai::Array) -> Dynamic {
|
||||
// Deserialize the contract
|
||||
let contract: ethereum::Contract = match serde_json::from_str(contract_json) {
|
||||
Ok(contract) => contract,
|
||||
@@ -761,6 +768,15 @@ fn call_contract_read(contract_json: &str, function_name: &str) -> Dynamic {
|
||||
}
|
||||
};
|
||||
|
||||
// Prepare the arguments
|
||||
let tokens = match prepare_function_arguments(&contract.abi, function_name, &args) {
|
||||
Ok(tokens) => tokens,
|
||||
Err(e) => {
|
||||
log::error!("Error preparing arguments: {}", e);
|
||||
return Dynamic::UNIT;
|
||||
}
|
||||
};
|
||||
|
||||
// Get the runtime
|
||||
let rt = match RUNTIME.lock() {
|
||||
Ok(rt) => rt,
|
||||
@@ -779,32 +795,11 @@ fn call_contract_read(contract_json: &str, function_name: &str) -> Dynamic {
|
||||
}
|
||||
};
|
||||
|
||||
// For simplicity, we're not handling arguments in this implementation
|
||||
let tokens: Vec<Token> = Vec::new();
|
||||
|
||||
// Execute the call in a blocking manner
|
||||
match rt.block_on(async {
|
||||
ethereum::call_read_function(&contract, &provider, function_name, tokens).await
|
||||
}) {
|
||||
Ok(result) => {
|
||||
// Convert the result to a Rhai value
|
||||
if result.is_empty() {
|
||||
Dynamic::UNIT
|
||||
} else {
|
||||
// For simplicity, we'll just return the first value as a string
|
||||
match &result[0] {
|
||||
Token::String(s) => Dynamic::from(s.clone()),
|
||||
Token::Uint(u) => Dynamic::from(u.to_string()),
|
||||
Token::Int(i) => Dynamic::from(i.to_string()),
|
||||
Token::Bool(b) => Dynamic::from(*b),
|
||||
Token::Address(a) => Dynamic::from(format!("{:?}", a)),
|
||||
_ => {
|
||||
log::error!("Unsupported return type");
|
||||
Dynamic::UNIT
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Ok(result) => convert_token_to_rhai(&result),
|
||||
Err(e) => {
|
||||
log::error!("Failed to call contract function: {}", e);
|
||||
Dynamic::UNIT
|
||||
@@ -812,8 +807,13 @@ fn call_contract_read(contract_json: &str, function_name: &str) -> Dynamic {
|
||||
}
|
||||
}
|
||||
|
||||
// Call a state-changing function on a contract
|
||||
fn call_contract_write(contract_json: &str, function_name: &str) -> String {
|
||||
// Call a state-changing function on a contract (no arguments version)
|
||||
fn call_contract_write_no_args(contract_json: &str, function_name: &str) -> String {
|
||||
call_contract_write(contract_json, function_name, rhai::Array::new())
|
||||
}
|
||||
|
||||
// Call a state-changing function on a contract with arguments
|
||||
fn call_contract_write(contract_json: &str, function_name: &str, args: rhai::Array) -> String {
|
||||
// Deserialize the contract
|
||||
let contract: ethereum::Contract = match serde_json::from_str(contract_json) {
|
||||
Ok(contract) => contract,
|
||||
@@ -823,6 +823,15 @@ fn call_contract_write(contract_json: &str, function_name: &str) -> String {
|
||||
}
|
||||
};
|
||||
|
||||
// Prepare the arguments
|
||||
let tokens = match prepare_function_arguments(&contract.abi, function_name, &args) {
|
||||
Ok(tokens) => tokens,
|
||||
Err(e) => {
|
||||
log::error!("Error preparing arguments: {}", e);
|
||||
return String::new();
|
||||
}
|
||||
};
|
||||
|
||||
// Get the runtime
|
||||
let rt = match RUNTIME.lock() {
|
||||
Ok(rt) => rt,
|
||||
@@ -851,15 +860,19 @@ fn call_contract_write(contract_json: &str, function_name: &str) -> String {
|
||||
}
|
||||
};
|
||||
|
||||
// For simplicity, we're not handling arguments in this implementation
|
||||
let tokens: Vec<Token> = Vec::new();
|
||||
|
||||
// Execute the transaction in a blocking manner
|
||||
match rt.block_on(async {
|
||||
ethereum::call_write_function(&contract, &wallet, &provider, function_name, tokens).await
|
||||
}) {
|
||||
Ok(tx_hash) => format!("{:?}", tx_hash),
|
||||
Err(e) => {
|
||||
// Log the error details for debugging
|
||||
log::debug!("\nERROR DETAILS: Transaction failed: {}", e);
|
||||
log::debug!("Contract address: {}", contract.address);
|
||||
log::debug!("Function: {}", function_name);
|
||||
log::debug!("Arguments: {:?}", args);
|
||||
log::debug!("Wallet address: {}", wallet.address);
|
||||
log::debug!("Network: {}", contract.network.name);
|
||||
log::error!("Transaction failed: {}", e);
|
||||
String::new()
|
||||
}
|
||||
@@ -917,7 +930,13 @@ pub fn register_crypto_module(engine: &mut Engine) -> Result<(), Box<EvalAltResu
|
||||
// Register smart contract functions
|
||||
engine.register_fn("load_contract_abi", load_contract_abi);
|
||||
engine.register_fn("load_contract_abi_from_file", load_contract_abi_from_file);
|
||||
|
||||
// Register the read function with different arities
|
||||
engine.register_fn("call_contract_read", call_contract_read_no_args);
|
||||
engine.register_fn("call_contract_read", call_contract_read);
|
||||
|
||||
// Register the write function with different arities
|
||||
engine.register_fn("call_contract_write", call_contract_write_no_args);
|
||||
engine.register_fn("call_contract_write", call_contract_write);
|
||||
|
||||
Ok(())
|
||||
|
Reference in New Issue
Block a user