mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-05-07 02:47:54 +00:00
Implement balance (#20)
This commit is contained in:
@@ -148,6 +148,12 @@ sol!(
|
||||
}
|
||||
);
|
||||
|
||||
sol!(
|
||||
contract Value {
|
||||
function balance_of(address _address) public view returns (uint ret);
|
||||
}
|
||||
);
|
||||
|
||||
impl Contract {
|
||||
/// Execute the contract.
|
||||
///
|
||||
@@ -490,6 +496,18 @@ impl Contract {
|
||||
calldata: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value_balance_of(address: Address) -> Self {
|
||||
let code = include_str!("../contracts/Value.sol");
|
||||
let name = "Value";
|
||||
|
||||
Self {
|
||||
name,
|
||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
||||
pvm_runtime: crate::compile_blob(name, code),
|
||||
calldata: Value::balance_ofCall::new((address,)).abi_encode(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -350,6 +350,10 @@ impl State {
|
||||
pub fn accounts(&self) -> &HashMap<Address, Account> {
|
||||
&self.accounts
|
||||
}
|
||||
|
||||
pub fn accounts_mut(&mut self) -> &mut HashMap<Address, Account> {
|
||||
&mut self.accounts
|
||||
}
|
||||
}
|
||||
|
||||
fn link_host_functions(engine: &Engine) -> Linker<Transaction> {
|
||||
@@ -902,6 +906,31 @@ fn link_host_functions(engine: &Engine) -> Linker<Transaction> {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
linker
|
||||
.func_wrap(
|
||||
runtime_api::imports::BALANCE,
|
||||
|caller: Caller<Transaction>, address_ptr: u32, balance_ptr: u32| -> Result<(), Trap> {
|
||||
let (mut caller, transaction) = caller.split();
|
||||
|
||||
let bytes = caller.read_memory_into_vec(address_ptr, 32)?;
|
||||
let word = U256::from_le_slice(&bytes);
|
||||
let address = Address::from_word(word.into());
|
||||
let balance = transaction
|
||||
.state
|
||||
.accounts()
|
||||
.get(&address)
|
||||
.map(|account| account.value)
|
||||
.unwrap_or(U256::default());
|
||||
|
||||
caller.write_memory(balance_ptr, &balance.to_le_bytes::<32>())?;
|
||||
|
||||
log::info!("account {address} balance {balance}");
|
||||
|
||||
Ok(())
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
linker
|
||||
}
|
||||
|
||||
|
||||
@@ -565,3 +565,28 @@ fn mcopy() {
|
||||
|
||||
assert_eq!(expected, received);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn balance() {
|
||||
let (_, output) = assert_success(&Contract::value_balance_of(Default::default()), false);
|
||||
|
||||
let expected = U256::ZERO;
|
||||
let received = U256::from_be_slice(&output.data);
|
||||
assert_eq!(expected, received);
|
||||
|
||||
let expected = U256::from(54589);
|
||||
let (mut state, address) = State::new_deployed(Contract::value_balance_of(Default::default()));
|
||||
state.accounts_mut().get_mut(&address).unwrap().value = expected;
|
||||
|
||||
let contract = Contract::value_balance_of(address);
|
||||
let (_, output) = state
|
||||
.transaction()
|
||||
.with_default_account(&contract.pvm_runtime)
|
||||
.calldata(contract.calldata)
|
||||
.call();
|
||||
|
||||
assert_eq!(ReturnFlags::Success, output.flags);
|
||||
|
||||
let received = U256::from_be_slice(&output.data);
|
||||
assert_eq!(expected, received)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user