rpc: transaction receipt test (#678)
* Problem: No test on the transaction receipt api Closes: #582 - add receipt rpc test for erc20 transfer logs * lower gas fee * build with go 1.17 in CI * use go 1.17 in test-solidity * fix merge
This commit is contained in:
parent
c644dd6707
commit
1000461a55
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@ -17,6 +17,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.3.5
|
- uses: actions/checkout@v2.3.5
|
||||||
|
- uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.17
|
||||||
- uses: technote-space/get-diff-action@v5
|
- uses: technote-space/get-diff-action@v5
|
||||||
id: git_diff
|
id: git_diff
|
||||||
with:
|
with:
|
||||||
|
3
.github/workflows/test.yml
vendored
3
.github/workflows/test.yml
vendored
@ -81,6 +81,9 @@ jobs:
|
|||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.3.5
|
- uses: actions/checkout@v2.3.5
|
||||||
|
- uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.17
|
||||||
- uses: technote-space/get-diff-action@v5
|
- uses: technote-space/get-diff-action@v5
|
||||||
id: git_diff
|
id: git_diff
|
||||||
with:
|
with:
|
||||||
|
@ -3,4 +3,4 @@
|
|||||||
# prepare sloc v0.5.17 in PATH
|
# prepare sloc v0.5.17 in PATH
|
||||||
solc --combined-json bin,abi --allow-paths . ./tests/solidity/suites/staking/contracts/test/mocks/StandardTokenMock.sol \
|
solc --combined-json bin,abi --allow-paths . ./tests/solidity/suites/staking/contracts/test/mocks/StandardTokenMock.sol \
|
||||||
| jq ".contracts.\"./tests/solidity/suites/staking/contracts/test/mocks/StandardTokenMock.sol:StandardTokenMock\"" \
|
| jq ".contracts.\"./tests/solidity/suites/staking/contracts/test/mocks/StandardTokenMock.sol:StandardTokenMock\"" \
|
||||||
> x/evm/keeper/ERC20Contract.json
|
> x/evm/types/ERC20Contract.json
|
||||||
|
@ -527,6 +527,84 @@ func TestEth_GetTransactionReceipt(t *testing.T) {
|
|||||||
require.Equal(t, []interface{}{}, receipt["logs"].([]interface{}))
|
require.Equal(t, []interface{}{}, receipt["logs"].([]interface{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deployTestERC20Contract deploys a contract that emits an event in the constructor
|
||||||
|
func deployTestERC20Contract(t *testing.T) common.Address {
|
||||||
|
param := make([]map[string]string, 1)
|
||||||
|
param[0] = make(map[string]string)
|
||||||
|
param[0]["from"] = "0x" + fmt.Sprintf("%x", from)
|
||||||
|
|
||||||
|
ctorArgs, err := evmtypes.ERC20Contract.ABI.Pack("", common.BytesToAddress(from), big.NewInt(100000000))
|
||||||
|
require.NoError(t, err)
|
||||||
|
data := append(evmtypes.ERC20Contract.Bin, ctorArgs...)
|
||||||
|
param[0]["data"] = hexutil.Encode(data)
|
||||||
|
|
||||||
|
param[0]["gas"] = "0x200000"
|
||||||
|
param[0]["gasPrice"] = "0x1"
|
||||||
|
|
||||||
|
rpcRes := call(t, "eth_sendTransaction", param)
|
||||||
|
|
||||||
|
var hash hexutil.Bytes
|
||||||
|
err = json.Unmarshal(rpcRes.Result, &hash)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
receipt := expectSuccessReceipt(t, hash)
|
||||||
|
contractAddress := common.HexToAddress(receipt["contractAddress"].(string))
|
||||||
|
require.NotEqual(t, common.Address{}, contractAddress)
|
||||||
|
|
||||||
|
require.NotNil(t, receipt["logs"])
|
||||||
|
|
||||||
|
return contractAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
// sendTestERC20Transaction sends a typical erc20 transfer transaction
|
||||||
|
func sendTestERC20Transaction(t *testing.T, contract common.Address, amount *big.Int) hexutil.Bytes {
|
||||||
|
// transfer
|
||||||
|
param := make([]map[string]string, 1)
|
||||||
|
param[0] = make(map[string]string)
|
||||||
|
param[0]["from"] = "0x" + fmt.Sprintf("%x", from)
|
||||||
|
param[0]["to"] = contract.Hex()
|
||||||
|
data, err := evmtypes.ERC20Contract.ABI.Pack("transfer", common.BigToAddress(big.NewInt(1)), amount)
|
||||||
|
require.NoError(t, err)
|
||||||
|
param[0]["data"] = hexutil.Encode(data)
|
||||||
|
param[0]["gas"] = "0x50000"
|
||||||
|
param[0]["gasPrice"] = "0x1"
|
||||||
|
|
||||||
|
rpcRes := call(t, "eth_sendTransaction", param)
|
||||||
|
|
||||||
|
var hash hexutil.Bytes
|
||||||
|
err = json.Unmarshal(rpcRes.Result, &hash)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEth_GetTransactionReceipt_ERC20Transfer(t *testing.T) {
|
||||||
|
// deploy erc20 contract
|
||||||
|
contract := deployTestERC20Contract(t)
|
||||||
|
amount := big.NewInt(10)
|
||||||
|
hash := sendTestERC20Transaction(t, contract, amount)
|
||||||
|
receipt := expectSuccessReceipt(t, hash)
|
||||||
|
|
||||||
|
require.Equal(t, 1, len(receipt["logs"].([]interface{})))
|
||||||
|
log := receipt["logs"].([]interface{})[0].(map[string]interface{})
|
||||||
|
|
||||||
|
require.Equal(t, contract, common.HexToAddress(log["address"].(string)))
|
||||||
|
|
||||||
|
valueBz, err := hexutil.Decode(log["data"].(string))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, amount, big.NewInt(0).SetBytes(valueBz))
|
||||||
|
|
||||||
|
require.Equal(t, false, log["removed"].(bool))
|
||||||
|
require.Equal(t, "0x0", log["logIndex"].(string))
|
||||||
|
require.Equal(t, "0x0", log["transactionIndex"].(string))
|
||||||
|
|
||||||
|
expectedTopics := []interface{}{
|
||||||
|
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
|
||||||
|
"0x000000000000000000000000" + fmt.Sprintf("%x", from),
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
||||||
|
}
|
||||||
|
require.Equal(t, expectedTopics, log["topics"].([]interface{}))
|
||||||
|
}
|
||||||
|
|
||||||
// deployTestContract deploys a contract that emits an event in the constructor
|
// deployTestContract deploys a contract that emits an event in the constructor
|
||||||
func deployTestContract(t *testing.T) (hexutil.Bytes, map[string]interface{}) {
|
func deployTestContract(t *testing.T) (hexutil.Bytes, map[string]interface{}) {
|
||||||
param := make([]map[string]string, 1)
|
param := make([]map[string]string, 1)
|
||||||
@ -592,6 +670,13 @@ func waitForReceipt(t *testing.T, hash hexutil.Bytes) map[string]interface{} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func expectSuccessReceipt(t *testing.T, hash hexutil.Bytes) map[string]interface{} {
|
||||||
|
receipt := waitForReceipt(t, hash)
|
||||||
|
require.NotNil(t, receipt, "transaction failed")
|
||||||
|
require.Equal(t, "0x1", receipt["status"].(string))
|
||||||
|
return receipt
|
||||||
|
}
|
||||||
|
|
||||||
func TestEth_GetFilterChanges_NoTopics(t *testing.T) {
|
func TestEth_GetFilterChanges_NoTopics(t *testing.T) {
|
||||||
rpcRes := call(t, "eth_blockNumber", []string{})
|
rpcRes := call(t, "eth_blockNumber", []string{})
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ func DoBenchmark(b *testing.B, txBuilder TxBuilder) {
|
|||||||
|
|
||||||
func BenchmarkTokenTransfer(b *testing.B) {
|
func BenchmarkTokenTransfer(b *testing.B) {
|
||||||
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
|
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
|
||||||
input, err := ContractABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
|
input, err := types.ERC20Contract.ABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
||||||
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), nil, nil, input, nil)
|
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), nil, nil, input, nil)
|
||||||
@ -72,7 +72,7 @@ func BenchmarkTokenTransfer(b *testing.B) {
|
|||||||
|
|
||||||
func BenchmarkEmitLogs(b *testing.B) {
|
func BenchmarkEmitLogs(b *testing.B) {
|
||||||
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
|
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
|
||||||
input, err := ContractABI.Pack("benchmarkLogs", big.NewInt(1000))
|
input, err := types.ERC20Contract.ABI.Pack("benchmarkLogs", big.NewInt(1000))
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
||||||
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 4100000, big.NewInt(1), nil, nil, input, nil)
|
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 4100000, big.NewInt(1), nil, nil, input, nil)
|
||||||
@ -81,7 +81,7 @@ func BenchmarkEmitLogs(b *testing.B) {
|
|||||||
|
|
||||||
func BenchmarkTokenTransferFrom(b *testing.B) {
|
func BenchmarkTokenTransferFrom(b *testing.B) {
|
||||||
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
|
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
|
||||||
input, err := ContractABI.Pack("transferFrom", suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(0))
|
input, err := types.ERC20Contract.ABI.Pack("transferFrom", suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(0))
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
||||||
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), nil, nil, input, nil)
|
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), nil, nil, input, nil)
|
||||||
@ -90,7 +90,7 @@ func BenchmarkTokenTransferFrom(b *testing.B) {
|
|||||||
|
|
||||||
func BenchmarkTokenMint(b *testing.B) {
|
func BenchmarkTokenMint(b *testing.B) {
|
||||||
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
|
DoBenchmark(b, func(suite *KeeperTestSuite, contract common.Address) *types.MsgEthereumTx {
|
||||||
input, err := ContractABI.Pack("mint", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
|
input, err := types.ERC20Contract.ABI.Pack("mint", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
nonce := suite.app.EvmKeeper.GetNonce(suite.address)
|
||||||
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), nil, nil, input, nil)
|
return types.NewTx(suite.app.EvmKeeper.ChainID(), nonce, &contract, big.NewInt(0), 410000, big.NewInt(1), nil, nil, input, nil)
|
||||||
|
@ -514,9 +514,9 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
|
|||||||
}, false, 0, false},
|
}, false, 0, false},
|
||||||
// estimate gas of an erc20 contract deployment, the exact gas number is checked with geth
|
// estimate gas of an erc20 contract deployment, the exact gas number is checked with geth
|
||||||
{"contract deployment", func() {
|
{"contract deployment", func() {
|
||||||
ctorArgs, err := ContractABI.Pack("", &suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
ctorArgs, err := types.ERC20Contract.ABI.Pack("", &suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
data := append(ContractBin, ctorArgs...)
|
data := append(types.ERC20Contract.Bin, ctorArgs...)
|
||||||
args = types.TransactionArgs{
|
args = types.TransactionArgs{
|
||||||
From: &suite.address,
|
From: &suite.address,
|
||||||
Data: (*hexutil.Bytes)(&data),
|
Data: (*hexutil.Bytes)(&data),
|
||||||
@ -526,7 +526,7 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
|
|||||||
{"erc20 transfer", func() {
|
{"erc20 transfer", func() {
|
||||||
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||||
suite.Commit()
|
suite.Commit()
|
||||||
transferData, err := ContractABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
|
transferData, err := types.ERC20Contract.ABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
args = types.TransactionArgs{To: &contractAddr, From: &suite.address, Data: (*hexutil.Bytes)(&transferData)}
|
args = types.TransactionArgs{To: &contractAddr, From: &suite.address, Data: (*hexutil.Bytes)(&transferData)}
|
||||||
}, true, 51880, false},
|
}, true, 51880, false},
|
||||||
@ -549,9 +549,9 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
|
|||||||
gasCap = 20000
|
gasCap = 20000
|
||||||
}, false, 0, true},
|
}, false, 0, true},
|
||||||
{"contract deployment w/ dynamicTxFee", func() {
|
{"contract deployment w/ dynamicTxFee", func() {
|
||||||
ctorArgs, err := ContractABI.Pack("", &suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
ctorArgs, err := types.ERC20Contract.ABI.Pack("", &suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
data := append(ContractBin, ctorArgs...)
|
data := append(types.ERC20Contract.Bin, ctorArgs...)
|
||||||
args = types.TransactionArgs{
|
args = types.TransactionArgs{
|
||||||
From: &suite.address,
|
From: &suite.address,
|
||||||
Data: (*hexutil.Bytes)(&data),
|
Data: (*hexutil.Bytes)(&data),
|
||||||
@ -560,7 +560,7 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
|
|||||||
{"erc20 transfer w/ dynamicTxFee", func() {
|
{"erc20 transfer w/ dynamicTxFee", func() {
|
||||||
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||||
suite.Commit()
|
suite.Commit()
|
||||||
transferData, err := ContractABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
|
transferData, err := types.ERC20Contract.ABI.Pack("transfer", common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), big.NewInt(1000))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
args = types.TransactionArgs{To: &contractAddr, From: &suite.address, Data: (*hexutil.Bytes)(&transferData)}
|
args = types.TransactionArgs{To: &contractAddr, From: &suite.address, Data: (*hexutil.Bytes)(&transferData)}
|
||||||
}, true, 51880, true},
|
}, true, 51880, true},
|
||||||
|
@ -27,7 +27,6 @@ import (
|
|||||||
ethermint "github.com/tharsis/ethermint/types"
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
"github.com/tharsis/ethermint/x/evm/types"
|
"github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
@ -40,29 +39,6 @@ import (
|
|||||||
"github.com/tendermint/tendermint/version"
|
"github.com/tendermint/tendermint/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
//go:embed ERC20Contract.json
|
|
||||||
compiledContractJSON []byte
|
|
||||||
ContractBin []byte
|
|
||||||
ContractABI abi.ABI
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
var tmp struct {
|
|
||||||
Abi string
|
|
||||||
Bin string
|
|
||||||
}
|
|
||||||
err := json.Unmarshal(compiledContractJSON, &tmp)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
ContractBin = common.FromHex(tmp.Bin)
|
|
||||||
err = json.Unmarshal([]byte(tmp.Abi), &ContractABI)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var testTokens = sdk.NewIntWithDecimal(1000, 18)
|
var testTokens = sdk.NewIntWithDecimal(1000, 18)
|
||||||
|
|
||||||
type KeeperTestSuite struct {
|
type KeeperTestSuite struct {
|
||||||
@ -193,10 +169,10 @@ func (suite *KeeperTestSuite) DeployTestContract(t require.TestingT, owner commo
|
|||||||
ctx := sdk.WrapSDKContext(suite.ctx)
|
ctx := sdk.WrapSDKContext(suite.ctx)
|
||||||
chainID := suite.app.EvmKeeper.ChainID()
|
chainID := suite.app.EvmKeeper.ChainID()
|
||||||
|
|
||||||
ctorArgs, err := ContractABI.Pack("", owner, supply)
|
ctorArgs, err := types.ERC20Contract.ABI.Pack("", owner, supply)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
data := append(ContractBin, ctorArgs...)
|
data := append(types.ERC20Contract.Bin, ctorArgs...)
|
||||||
args, err := json.Marshal(&types.TransactionArgs{
|
args, err := json.Marshal(&types.TransactionArgs{
|
||||||
From: &suite.address,
|
From: &suite.address,
|
||||||
Data: (*hexutil.Bytes)(&data),
|
Data: (*hexutil.Bytes)(&data),
|
||||||
@ -250,7 +226,7 @@ func (suite *KeeperTestSuite) TransferERC20Token(t require.TestingT, contractAdd
|
|||||||
ctx := sdk.WrapSDKContext(suite.ctx)
|
ctx := sdk.WrapSDKContext(suite.ctx)
|
||||||
chainID := suite.app.EvmKeeper.ChainID()
|
chainID := suite.app.EvmKeeper.ChainID()
|
||||||
|
|
||||||
transferData, err := ContractABI.Pack("transfer", to, amount)
|
transferData, err := types.ERC20Contract.ABI.Pack("transfer", to, amount)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
args, err := json.Marshal(&types.TransactionArgs{To: &contractAddr, From: &from, Data: (*hexutil.Bytes)(&transferData)})
|
args, err := json.Marshal(&types.TransactionArgs{To: &contractAddr, From: &from, Data: (*hexutil.Bytes)(&transferData)})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
88
x/evm/types/compiled_contract.go
Normal file
88
x/evm/types/compiled_contract.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
// embed compiled smart contract
|
||||||
|
_ "embed"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HexString is a byte array that serializes to hex
|
||||||
|
type HexString []byte
|
||||||
|
|
||||||
|
// MarshalJSON serializes ByteArray to hex
|
||||||
|
func (s HexString) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(fmt.Sprintf("%x", string(s)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON deserializes ByteArray to hex
|
||||||
|
func (s *HexString) UnmarshalJSON(data []byte) error {
|
||||||
|
var x string
|
||||||
|
if err := json.Unmarshal(data, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
str, err := hex.DecodeString(x)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*s = str
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompiledContract contains compiled bytecode and abi
|
||||||
|
type CompiledContract struct {
|
||||||
|
ABI abi.ABI
|
||||||
|
Bin HexString
|
||||||
|
}
|
||||||
|
|
||||||
|
type jsonCompiledContract struct {
|
||||||
|
ABI string
|
||||||
|
Bin HexString
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON serializes ByteArray to hex
|
||||||
|
func (s CompiledContract) MarshalJSON() ([]byte, error) {
|
||||||
|
abi1, err := json.Marshal(s.ABI)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return json.Marshal(jsonCompiledContract{ABI: string(abi1), Bin: s.Bin})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON deserializes ByteArray to hex
|
||||||
|
func (s *CompiledContract) UnmarshalJSON(data []byte) error {
|
||||||
|
var x jsonCompiledContract
|
||||||
|
if err := json.Unmarshal(data, &x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Bin = x.Bin
|
||||||
|
if err := json.Unmarshal([]byte(x.ABI), &s.ABI); err != nil {
|
||||||
|
fmt.Println("unmarshal abi fail", x.ABI, string(data))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
//go:embed ERC20Contract.json
|
||||||
|
erc20JSON []byte
|
||||||
|
|
||||||
|
// ERC20Contract is the compiled test erc20 contract
|
||||||
|
ERC20Contract CompiledContract
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
err := json.Unmarshal(erc20JSON, &ERC20Contract)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ERC20Contract.Bin) == 0 {
|
||||||
|
panic("load contract failed")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user