Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs/move get balance.sol from wiki #3448

Merged
merged 14 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/evm/evmtest/GetBalance.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"agentID","type":"bytes"}],"name":"GotAgentID","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"baseBalance","type":"uint64"}],"name":"GotBaseBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nftBalance","type":"uint256"}],"name":"GotNFTIDs","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nativeTokenBalance","type":"uint256"}],"name":"GotNativeTokenBalance","type":"event"},{"inputs":[{"internalType":"bytes","name":"nativeTokenID","type":"bytes"}],"name":"getBalance","outputs":[],"stateMutability":"nonpayable","type":"function"}]
1 change: 1 addition & 0 deletions packages/evm/evmtest/GetBalance.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
608060405234801561000f575f80fd5b506108ef8061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063d0fc35011461002d575b5f80fd5b610047600480360381019061004291906104c5565b610049565b005b5f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f31317496040518163ffffffff1660e01b81526004015f60405180830381865afa1580156100a6573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906100ce91906105ff565b90507f28b3d377892d8db500fb9a9bbd4731605ca2a642c3c62a7e64d47b7d42024368815f01516040516101029190610698565b60405180910390a15f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b019204f836040518263ffffffff1660e01b81526004016101589190610727565b602060405180830381865afa158015610173573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101979190610784565b90507f23ce6861f26687742455d6955fcd53a5587ecf279e37422d0cd9636e2a2a9f7f816040516101c891906107be565b60405180910390a15f60405180602001604052808581525090505f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ef43e40d83866040518363ffffffff1660e01b81526004016102329291906107fe565b602060405180830381865afa15801561024d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102719190610866565b90507fab4abdf0d66655ed9c7e1ee2f2aff1d43dbdc0736a3e7078c2be95bcf3800575816040516102a291906108a0565b60405180910390a15f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630d90ec7b866040518263ffffffff1660e01b81526004016102f89190610727565b602060405180830381865afa158015610313573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103379190610866565b90507f52c249d568f18754049ea99591153f1f0ad8c7ab03a3bcdcf8454bc274e541018160405161036891906108a0565b60405180910390a1505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6103d782610391565b810181811067ffffffffffffffff821117156103f6576103f56103a1565b5b80604052505050565b5f610408610378565b905061041482826103ce565b919050565b5f67ffffffffffffffff821115610433576104326103a1565b5b61043c82610391565b9050602081019050919050565b828183375f83830152505050565b5f61046961046484610419565b6103ff565b9050828152602081018484840111156104855761048461038d565b5b610490848285610449565b509392505050565b5f82601f8301126104ac576104ab610389565b5b81356104bc848260208601610457565b91505092915050565b5f602082840312156104da576104d9610381565b5b5f82013567ffffffffffffffff8111156104f7576104f6610385565b5b61050384828501610498565b91505092915050565b5f80fd5b5f80fd5b5f5b83811015610531578082015181840152602081019050610516565b5f8484015250505050565b5f61054e61054984610419565b6103ff565b90508281526020810184848401111561056a5761056961038d565b5b610575848285610514565b509392505050565b5f82601f83011261059157610590610389565b5b81516105a184826020860161053c565b91505092915050565b5f602082840312156105bf576105be61050c565b5b6105c960206103ff565b90505f82015167ffffffffffffffff8111156105e8576105e7610510565b5b6105f48482850161057d565b5f8301525092915050565b5f6020828403121561061457610613610381565b5b5f82015167ffffffffffffffff81111561063157610630610385565b5b61063d848285016105aa565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f61066a82610646565b6106748185610650565b9350610684818560208601610514565b61068d81610391565b840191505092915050565b5f6020820190508181035f8301526106b08184610660565b905092915050565b5f82825260208201905092915050565b5f6106d282610646565b6106dc81856106b8565b93506106ec818560208601610514565b6106f581610391565b840191505092915050565b5f602083015f8301518482035f86015261071a82826106c8565b9150508091505092915050565b5f6020820190508181035f83015261073f8184610700565b905092915050565b5f67ffffffffffffffff82169050919050565b61076381610747565b811461076d575f80fd5b50565b5f8151905061077e8161075a565b92915050565b5f6020828403121561079957610798610381565b5b5f6107a684828501610770565b91505092915050565b6107b881610747565b82525050565b5f6020820190506107d15f8301846107af565b92915050565b5f602083015f8301518482035f8601526107f182826106c8565b9150508091505092915050565b5f6040820190508181035f83015261081681856107d7565b9050818103602083015261082a8184610700565b90509392505050565b5f819050919050565b61084581610833565b811461084f575f80fd5b50565b5f815190506108608161083c565b92915050565b5f6020828403121561087b5761087a610381565b5b5f61088884828501610852565b91505092915050565b61089a81610833565b82525050565b5f6020820190506108b35f830184610891565b9291505056fea264697066735822122090eb26ecd9fcc4785bf94129a00cd83e3e9f7eee6f59bc51191d4984ac66195064736f6c63430008140033
27 changes: 27 additions & 0 deletions packages/evm/evmtest/GetBalance.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@iscmagic/ISC.sol";

contract GetBalance {
event GotAgentID(bytes agentID);
event GotBaseBalance(uint64 baseBalance);
event GotNativeTokenBalance(uint256 nativeTokenBalance);
event GotNFTIDs(uint256 nftBalance);

function getBalance(bytes memory nativeTokenID) public {
ISCAgentID memory agentID = ISC.sandbox.getSenderAccount();
emit GotAgentID(agentID.data);

uint64 baseBalance = ISC.accounts.getL2BalanceBaseTokens(agentID);
emit GotBaseBalance(baseBalance);

NativeTokenID memory id = NativeTokenID({ data: nativeTokenID});
uint256 nativeTokens = ISC.accounts.getL2BalanceNativeTokens(id, agentID);
emit GotNativeTokenBalance(nativeTokens);

uint256 nfts = ISC.accounts.getL2NFTAmount(agentID);
emit GotNFTIDs(nfts);
salaheldinsoliman marked this conversation as resolved.
Show resolved Hide resolved
}
}
9 changes: 9 additions & 0 deletions packages/evm/evmtest/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ var (
ISCTestContractBytecode = common.FromHex(strings.TrimSpace(iscTestContractBytecodeHex))
)

//go:generate sh -c "solc --abi --bin --overwrite @iscmagic=`realpath ../../vm/core/evm/iscmagic` GetBalance.sol -o ."
var (
//go:embed GetBalance.abi
GetBalanceContractABI string
//go:embed GetBalance.bin
GetBalanceContractBytecodeHex string
GetBalanceContractBytecode = common.FromHex(strings.TrimSpace(GetBalanceContractBytecodeHex))
)

//go:generate solc --abi --bin --overwrite Fibonacci.sol -o .
var (
//go:embed Fibonacci.abi
Expand Down
16 changes: 16 additions & 0 deletions packages/vm/core/evm/evmtest/contractInstance.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/ecdsa"
"fmt"
"math/big"
"slices"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
Expand Down Expand Up @@ -152,6 +153,21 @@ func (e *EVMContractInstance) CallFnExpectEvent(opts []ethCallOptions, eventName
return res
}

// If a Solidity function emits multiple events, this function will return the first event that matches the given eventName
func (e *EVMContractInstance) CallFnExpectMultipleEvents(opts []ethCallOptions, eventName string, v interface{}, fnName string, args ...interface{}) CallFnResult {
res, err := e.CallFn(opts, fnName, args...)
require.NoError(e.chain.t, err)
require.Equal(e.chain.t, types.ReceiptStatusSuccessful, res.EVMReceipt.Status)
topic := e.abi.Events[eventName].ID
for _, log := range res.EVMReceipt.Logs {
if slices.Contains(log.Topics, topic) {
err = e.abi.UnpackIntoInterface(v, eventName, log.Data)
}
require.NoError(e.chain.t, err)
}
return res
}
salaheldinsoliman marked this conversation as resolved.
Show resolved Hide resolved

func (e *EVMContractInstance) callView(fnName string, args []interface{}, v interface{}, blockNumberOrHash ...rpc.BlockNumberOrHash) error {
e.chain.t.Logf("callView: %s %+v", fnName, args)
callArguments, err := e.abi.Pack(fnName, args...)
Expand Down
73 changes: 73 additions & 0 deletions packages/vm/core/evm/evmtest/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/rpc"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

iotago "github.com/iotaledger/iota.go/v3"
Expand Down Expand Up @@ -2729,3 +2730,75 @@ func TestDisableMagicWrap(t *testing.T) {
envWithMagicWrap := InitEVM(t, true)
require.NotNil(t, envWithMagicWrap.getCode(envWithMagicWrap.ERC20BaseTokens(nil).address))
}

func TestGetBalance(t *testing.T) {
env := InitEVMWithSolo(t, solo.New(t), true)
privateKey, deployer := env.Chain.NewEthereumAccountWithL2Funds()

instance := env.DeployContract(privateKey, evmtest.GetBalanceContractABI, evmtest.GetBalanceContractBytecode)

// create a new native token on L1
foundry, tokenID, err := env.Chain.NewNativeTokenParams(100000000000000).CreateFoundry()
require.NoError(t, err)
// the token id in bytes, used to call the contract
nativeTokenIDBytes := isc.NativeTokenIDToBytes(tokenID)

// mint some native tokens to the chain originator
err = env.Chain.MintTokens(foundry, 10000000, env.Chain.OriginatorPrivateKey)
require.NoError(t, err)

// get the agentId of the contract deployer
senderAgentID := isc.NewEthereumAddressAgentID(env.Chain.ChainID, deployer)

// test 1
// get the actual base balance of the contract deployer
// and compare it with the balance returned by the contract
balance, _ := env.Chain.EVM().Balance(deployer, nil)
decimals := env.Chain.EVM().BaseToken().Decimals
var value uint64
instance.CallFnExpectMultipleEvents(nil, "GotBaseBalance", &value, "getBalance", nativeTokenIDBytes)
realBalance := util.BaseTokensDecimalsToEthereumDecimals(value, decimals)
assert.Equal(t, balance, realBalance)

// test 2
// get the agnetId of the contract deployer
// and compare it with the agentId returned by the contract
var adgntID []byte
salaheldinsoliman marked this conversation as resolved.
Show resolved Hide resolved
instance.CallFnExpectMultipleEvents(nil, "GotAgentID", &adgntID, "getBalance", nativeTokenIDBytes)
assert.Equal(t, senderAgentID.Bytes(), adgntID)

// test 3
// get the native token balance of the contract deployer
// It should be 0, because the contract deployer has not received any native tokens yet
nativeBalance := new(big.Int)
instance.CallFnExpectMultipleEvents(nil, "GotNativeTokenBalance", &nativeBalance, "getBalance", nativeTokenIDBytes)
assert.Equal(t, int64(0), nativeBalance.Int64())

// test 4
// send some native tokens to the contract deployer
// and check if the balance returned by the contract is correct
err = env.Chain.SendFromL2ToL2AccountNativeTokens(tokenID, senderAgentID, 100000, env.Chain.OriginatorPrivateKey)
require.NoError(t, err)
instance.CallFnExpectMultipleEvents(nil, "GotNativeTokenBalance", &nativeBalance, "getBalance", nativeTokenIDBytes)
assert.Equal(t, int64(100000), nativeBalance.Int64())

// test 5
// mint an NFToken to the contract deployer
// and check if the balance returned by the contract is correct
mockMetaData := []byte("sesa")
nfti, info, err := env.Chain.Env.MintNFTL1(env.Chain.OriginatorPrivateKey, env.Chain.OriginatorAddress, mockMetaData)
require.NoError(t, err)
env.Chain.MustDepositNFT(nfti, env.Chain.OriginatorAgentID, env.Chain.OriginatorPrivateKey)

transfer := isc.NewEmptyAssets()
transfer.AddNFTs(info.NFTID)

// send the NFT to the contract deployer
err = env.Chain.SendFromL2ToL2Account(transfer, senderAgentID, env.Chain.OriginatorPrivateKey)
require.NoError(t, err)

// get the NFT balance of the contract deployer
nftBalance := new(big.Int)
instance.CallFnExpectMultipleEvents(nil, "GotNFTIDs", &nftBalance, "getBalance", nativeTokenIDBytes)
assert.Equal(t, int64(1), nftBalance.Int64())
}
Loading