mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-13 01:41:00 +00:00
Implement balance (#20)
This commit is contained in:
@@ -6,4 +6,8 @@ contract Value {
|
|||||||
function value() public payable returns (uint ret) {
|
function value() public payable returns (uint ret) {
|
||||||
ret = msg.value;
|
ret = msg.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function balance_of(address _address) public view returns (uint ret) {
|
||||||
|
ret = _address.balance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,6 +148,12 @@ sol!(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
sol!(
|
||||||
|
contract Value {
|
||||||
|
function balance_of(address _address) public view returns (uint ret);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
impl Contract {
|
impl Contract {
|
||||||
/// Execute the contract.
|
/// Execute the contract.
|
||||||
///
|
///
|
||||||
@@ -490,6 +496,18 @@ impl Contract {
|
|||||||
calldata: Default::default(),
|
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)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -350,6 +350,10 @@ impl State {
|
|||||||
pub fn accounts(&self) -> &HashMap<Address, Account> {
|
pub fn accounts(&self) -> &HashMap<Address, Account> {
|
||||||
&self.accounts
|
&self.accounts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn accounts_mut(&mut self) -> &mut HashMap<Address, Account> {
|
||||||
|
&mut self.accounts
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn link_host_functions(engine: &Engine) -> Linker<Transaction> {
|
fn link_host_functions(engine: &Engine) -> Linker<Transaction> {
|
||||||
@@ -902,6 +906,31 @@ fn link_host_functions(engine: &Engine) -> Linker<Transaction> {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.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
|
linker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -565,3 +565,28 @@ fn mcopy() {
|
|||||||
|
|
||||||
assert_eq!(expected, received);
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ pub mod exports {
|
|||||||
pub mod imports {
|
pub mod imports {
|
||||||
pub static ADDRESS: &str = "address";
|
pub static ADDRESS: &str = "address";
|
||||||
|
|
||||||
|
pub static BALANCE: &str = "balance";
|
||||||
|
|
||||||
pub static BLOCK_NUMBER: &str = "block_number";
|
pub static BLOCK_NUMBER: &str = "block_number";
|
||||||
|
|
||||||
pub static CALL: &str = "seal_call";
|
pub static CALL: &str = "seal_call";
|
||||||
@@ -45,8 +47,9 @@ pub mod imports {
|
|||||||
|
|
||||||
/// All imported runtime API symbols.
|
/// All imported runtime API symbols.
|
||||||
/// Useful for configuring common attributes and linkage.
|
/// Useful for configuring common attributes and linkage.
|
||||||
pub static IMPORTS: [&str; 15] = [
|
pub static IMPORTS: [&str; 16] = [
|
||||||
ADDRESS,
|
ADDRESS,
|
||||||
|
BALANCE,
|
||||||
BLOCK_NUMBER,
|
BLOCK_NUMBER,
|
||||||
CALL,
|
CALL,
|
||||||
CALLER,
|
CALLER,
|
||||||
|
|||||||
@@ -41,11 +41,31 @@ where
|
|||||||
|
|
||||||
/// Translates the `balance` instructions.
|
/// Translates the `balance` instructions.
|
||||||
pub fn balance<'ctx, D>(
|
pub fn balance<'ctx, D>(
|
||||||
_context: &mut Context<'ctx, D>,
|
context: &mut Context<'ctx, D>,
|
||||||
_address: inkwell::values::IntValue<'ctx>,
|
address: inkwell::values::IntValue<'ctx>,
|
||||||
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
|
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
|
||||||
where
|
where
|
||||||
D: Dependency + Clone,
|
D: Dependency + Clone,
|
||||||
{
|
{
|
||||||
todo!()
|
let balance_pointer = context.build_alloca(context.word_type(), "balance_pointer");
|
||||||
|
let address_pointer = context.build_alloca(context.word_type(), "address_pointer");
|
||||||
|
context.build_store(address_pointer, address)?;
|
||||||
|
|
||||||
|
let balance = context.builder().build_ptr_to_int(
|
||||||
|
balance_pointer.value,
|
||||||
|
context.xlen_type(),
|
||||||
|
"balance",
|
||||||
|
)?;
|
||||||
|
let address = context.builder().build_ptr_to_int(
|
||||||
|
address_pointer.value,
|
||||||
|
context.xlen_type(),
|
||||||
|
"address",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
context.build_runtime_call(
|
||||||
|
runtime_api::imports::BALANCE,
|
||||||
|
&[address.into(), balance.into()],
|
||||||
|
);
|
||||||
|
|
||||||
|
context.build_load(balance_pointer, "balance")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user