diff --git a/contracts.go b/contracts.go index 8df01db..e30fb86 100644 --- a/contracts.go +++ b/contracts.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) @@ -27,14 +28,23 @@ type Contract interface { // Pack packs the method and arguments into a byte array representing // the smart contract call data Pack( + wallet *Wallet, method string, arguments json.RawMessage) ([]byte, error) // Parse parses the arguments as JSON format into an array of smart // contract function call arguments Parse( + wallet *Wallet, method string, arguments json.RawMessage) ([]interface{}, error) + + // EstimateGasLimit estimates the gas limit for a smart contract method call + EstimateGasLimit( + wallet *Wallet, + contractAddr common.Address, + method string, + arguments json.RawMessage) (uint64, error) } // ContractFactory is a function that takes an address and return a Contract instance diff --git a/contracts/feralfile-airdrop-v1/airdrop.go b/contracts/feralfile-airdrop-v1/airdrop.go index bfffd2c..ffa85b6 100644 --- a/contracts/feralfile-airdrop-v1/airdrop.go +++ b/contracts/feralfile-airdrop-v1/airdrop.go @@ -1,12 +1,14 @@ package airdropv1 import ( + "context" "encoding/json" "fmt" "math/big" ethereum "github.com/bitmark-inc/account-vault-ethereum" airdropv1 "github.com/bitmark-inc/feralfile-exhibition-smart-contract/go-binding/feralfile-airdrop-v1" + goEthereum "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" @@ -66,8 +68,9 @@ func (c *FeralFileAirdropV1Contract) Call( noSend bool, customizeGasPriceInWei *int64, customizedNonce *uint64) (*types.Transaction, error) { + contractAddr := common.HexToAddress(c.contractAddress) contract, err := airdropv1.NewFeralFileAirdropV1( - common.HexToAddress(c.contractAddress), + contractAddr, wallet.RPCClient()) if err != nil { return nil, err @@ -87,7 +90,7 @@ func (c *FeralFileAirdropV1Contract) Call( t.Nonce = big.NewInt(int64(*customizedNonce)) } - params, err := c.Parse(method, arguments) + params, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } @@ -108,7 +111,12 @@ func (c *FeralFileAirdropV1Contract) Call( return nil, fmt.Errorf("invalid amount") } - t.GasLimit = 100000 + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.Mint(t, tokenID, amount) case "airdrop": if len(params) != 2 { @@ -125,8 +133,12 @@ func (c *FeralFileAirdropV1Contract) Call( return nil, fmt.Errorf("invalid to address") } - const gasLimitPerItem = 150000 - t.GasLimit = uint64(gasLimitPerItem * len(to)) + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.Airdrop(t, tokenID, to) } @@ -135,6 +147,7 @@ func (c *FeralFileAirdropV1Contract) Call( } func (c *FeralFileAirdropV1Contract) Pack( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]byte, error) { abi, err := airdropv1.FeralFileAirdropV1MetaData.GetAbi() @@ -142,7 +155,7 @@ func (c *FeralFileAirdropV1Contract) Pack( return nil, err } - parsedArgs, err := c.Parse(method, arguments) + parsedArgs, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } @@ -151,6 +164,7 @@ func (c *FeralFileAirdropV1Contract) Pack( } func (c *FeralFileAirdropV1Contract) Parse( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]interface{}, error) { switch method { @@ -184,6 +198,29 @@ func (c *FeralFileAirdropV1Contract) Parse( } } +func (c *FeralFileAirdropV1Contract) EstimateGasLimit( + wallet *ethereum.Wallet, + contractAddr common.Address, + method string, + arguments json.RawMessage) (uint64, error) { + data, err := c.Pack(wallet, method, arguments) + if nil != err { + return 0, err + } + + gas, err := wallet.RPCClient().EstimateGas(context.Background(), goEthereum.CallMsg{ + From: common.HexToAddress(wallet.Account()), + To: &contractAddr, + Data: data, + }) + + if nil != err { + return 0, err + } + + return gas * 115 / 100, nil // add 15% buffer +} + func init() { ethereum.RegisterContract("FeralFileAirdropV1", FeralFileAirdropV1ContractFactory) } diff --git a/contracts/feralfile-english-auction/english_auction.go b/contracts/feralfile-english-auction/english_auction.go index 82305d0..790df3d 100644 --- a/contracts/feralfile-english-auction/english_auction.go +++ b/contracts/feralfile-english-auction/english_auction.go @@ -1,6 +1,7 @@ package english_auction import ( + "context" "encoding/hex" "encoding/json" "errors" @@ -9,6 +10,7 @@ import ( "strconv" "strings" + goEthereum "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" @@ -60,7 +62,8 @@ func (c *FeralfileEnglishAuctionContract) Call( noSend bool, customizeGasPriceInWei *int64, customizedNonce *uint64) (*types.Transaction, error) { - contract, err := english_auction.NewFeralfileEnglishAuction(common.HexToAddress(c.contractAddress), wallet.RPCClient()) + contractAddr := common.HexToAddress(c.contractAddress) + contract, err := english_auction.NewFeralfileEnglishAuction(contractAddr, wallet.RPCClient()) if err != nil { return nil, err } @@ -78,7 +81,7 @@ func (c *FeralfileEnglishAuctionContract) Call( t.Nonce = big.NewInt(int64(*customizedNonce)) } - params, err := c.Parse(method, arguments) + params, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } @@ -94,6 +97,13 @@ func (c *FeralfileEnglishAuctionContract) Call( return nil, fmt.Errorf("invalid auctions params") } + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit + return contract.RegisterAuctions(t, auctions) case "placeSignedBid": if len(params) != 7 { @@ -203,6 +213,7 @@ func (c *FeralfileEnglishAuctionContract) Call( } func (c *FeralfileEnglishAuctionContract) Pack( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]byte, error) { abi, err := english_auction.FeralfileEnglishAuctionMetaData.GetAbi() @@ -210,7 +221,7 @@ func (c *FeralfileEnglishAuctionContract) Pack( return nil, err } - parsedArgs, err := c.Parse(method, arguments) + parsedArgs, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } @@ -219,6 +230,7 @@ func (c *FeralfileEnglishAuctionContract) Pack( } func (c *FeralfileEnglishAuctionContract) Parse( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]interface{}, error) { switch method { @@ -390,6 +402,29 @@ func (c *FeralfileEnglishAuctionContract) Parse( } } +func (c *FeralfileEnglishAuctionContract) EstimateGasLimit( + wallet *ethereum.Wallet, + contractAddr common.Address, + method string, + arguments json.RawMessage) (uint64, error) { + data, err := c.Pack(wallet, method, arguments) + if nil != err { + return 0, err + } + + gas, err := wallet.RPCClient().EstimateGas(context.Background(), goEthereum.CallMsg{ + From: common.HexToAddress(wallet.Account()), + To: &contractAddr, + Data: data, + }) + + if nil != err { + return 0, err + } + + return gas * 115 / 100, nil // add 15% buffer +} + func init() { ethereum.RegisterContract("FeralfileEnglishAuction", FeralfileEnglishAuctionFactory) } diff --git a/contracts/feralfile-exhibition-v2/feralfile.go b/contracts/feralfile-exhibition-v2/feralfile.go index db2708d..84afeae 100644 --- a/contracts/feralfile-exhibition-v2/feralfile.go +++ b/contracts/feralfile-exhibition-v2/feralfile.go @@ -1,10 +1,12 @@ package feralfilev2 import ( + "context" "encoding/json" "fmt" "math/big" + goEthereum "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" @@ -13,12 +15,6 @@ import ( feralfilev2 "github.com/bitmark-inc/feralfile-exhibition-smart-contract/go-binding/feralfile-exhibition-v2" ) -const ( - GasLimitSwapArtworkFromBitmark = 400000 - GasLimitTransfer = 120000 - GasLimitApproveForAll = 60000 -) - type FeralfileExhibitionV2Contract struct { contractAddress string } @@ -72,7 +68,8 @@ func (c *FeralfileExhibitionV2Contract) Call( noSend bool, customizeGasPriceInWei *int64, customizedNonce *uint64) (*types.Transaction, error) { - contract, err := feralfilev2.NewFeralfileExhibitionV2(common.HexToAddress(c.contractAddress), wallet.RPCClient()) + contractAddr := common.HexToAddress(c.contractAddress) + contract, err := feralfilev2.NewFeralfileExhibitionV2(contractAddr, wallet.RPCClient()) if err != nil { return nil, err } @@ -91,7 +88,7 @@ func (c *FeralfileExhibitionV2Contract) Call( t.Nonce = big.NewInt(int64(*customizedNonce)) } - params, err := c.Parse(method, arguments) + params, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } @@ -158,7 +155,12 @@ func (c *FeralfileExhibitionV2Contract) Call( return nil, fmt.Errorf("invalid ipfs cid params") } - t.GasLimit = GasLimitSwapArtworkFromBitmark + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.SwapArtworkFromBitmark( t, @@ -182,7 +184,12 @@ func (c *FeralfileExhibitionV2Contract) Call( return nil, fmt.Errorf("invalid token id params") } - t.GasLimit = GasLimitTransfer + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.SafeTransferFrom( t, @@ -199,7 +206,12 @@ func (c *FeralfileExhibitionV2Contract) Call( return nil, fmt.Errorf("invalid operator params") } - t.GasLimit = GasLimitApproveForAll + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.SetApprovalForAll(t, operator, true) default: @@ -208,6 +220,7 @@ func (c *FeralfileExhibitionV2Contract) Call( } func (c *FeralfileExhibitionV2Contract) Pack( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]byte, error) { abi, err := feralfilev2.FeralfileExhibitionV2MetaData.GetAbi() @@ -215,15 +228,29 @@ func (c *FeralfileExhibitionV2Contract) Pack( return nil, err } - parsedArgs, err := c.Parse(method, arguments) + parsedArgs, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } + switch method { + case "create_artwork": + method = "createArtwork" + case "swap_artwork_from_bitmark": + method = "swapArtworkFromBitmark" + case "transfer": + method = "safeTransferFrom" + case "approve_for_all": + method = "setApprovalForAll" + default: + return nil, fmt.Errorf("unsupported method") + } + return abi.Pack(method, parsedArgs...) } func (c *FeralfileExhibitionV2Contract) Parse( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]interface{}, error) { switch method { @@ -262,7 +289,8 @@ func (c *FeralfileExhibitionV2Contract) Parse( ¶ms.ArtworkID.Int, ¶ms.BitmarkID.Int, ¶ms.EditionNumber.Int, - params.To, params.IPFSCID}, nil + params.To, + params.IPFSCID}, nil case "transfer": var params struct { To common.Address `json:"to"` @@ -272,7 +300,7 @@ func (c *FeralfileExhibitionV2Contract) Parse( return nil, err } - return []interface{}{params.To, ¶ms.TokenID.Int}, nil + return []interface{}{common.HexToAddress(wallet.Account()), params.To, ¶ms.TokenID.Int}, nil case "approve_for_all": var params struct { @@ -282,12 +310,35 @@ func (c *FeralfileExhibitionV2Contract) Parse( return nil, err } - return []interface{}{params.Operator}, nil + return []interface{}{params.Operator, true}, nil default: return nil, fmt.Errorf("unsupported method") } } +func (c *FeralfileExhibitionV2Contract) EstimateGasLimit( + wallet *ethereum.Wallet, + contractAddr common.Address, + method string, + arguments json.RawMessage) (uint64, error) { + data, err := c.Pack(wallet, method, arguments) + if nil != err { + return 0, err + } + + gas, err := wallet.RPCClient().EstimateGas(context.Background(), goEthereum.CallMsg{ + From: common.HexToAddress(wallet.Account()), + To: &contractAddr, + Data: data, + }) + + if nil != err { + return 0, err + } + + return gas * 115 / 100, nil // add 15% buffer +} + func init() { ethereum.RegisterContract("FeralfileExhibitionV2", FeralfileExhibitionV2ContractFactory) } diff --git a/contracts/feralfile-exhibition-v3/feralfile.go b/contracts/feralfile-exhibition-v3/feralfile.go index 94a63d4..c23656a 100644 --- a/contracts/feralfile-exhibition-v3/feralfile.go +++ b/contracts/feralfile-exhibition-v3/feralfile.go @@ -1,6 +1,7 @@ package feralfilev3 import ( + "context" "encoding/hex" "encoding/json" "errors" @@ -9,6 +10,7 @@ import ( "strconv" "strings" + goEthereum "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" @@ -17,13 +19,6 @@ import ( feralfilev3 "github.com/bitmark-inc/feralfile-exhibition-smart-contract/go-binding/feralfile-exhibition-v3" ) -const ( - GasLimitPerMint = 450000 - GasLimitPerAuthTransfer = 150000 - GasLimitTransfer = 120000 - GasLimitApproveForAll = 80000 -) - type FeralfileExhibitionV3Contract struct { contractAddress string } @@ -77,7 +72,8 @@ func (c *FeralfileExhibitionV3Contract) Call( noSend bool, customizeGasPriceInWei *int64, customizedNonce *uint64) (*types.Transaction, error) { - contract, err := feralfilev3.NewFeralfileExhibitionV3(common.HexToAddress(c.contractAddress), wallet.RPCClient()) + contractAddr := common.HexToAddress(c.contractAddress) + contract, err := feralfilev3.NewFeralfileExhibitionV3(contractAddr, wallet.RPCClient()) if err != nil { return nil, err } @@ -96,7 +92,7 @@ func (c *FeralfileExhibitionV3Contract) Call( t.Nonce = big.NewInt(int64(*customizedNonce)) } - params, err := c.Parse(method, arguments) + params, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } @@ -123,7 +119,12 @@ func (c *FeralfileExhibitionV3Contract) Call( return nil, fmt.Errorf("invalid mint params") } - t.GasLimit = uint64(GasLimitPerMint * len(mintParams)) + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.BatchMint(t, mintParams) case "authorized_transfer": @@ -136,7 +137,12 @@ func (c *FeralfileExhibitionV3Contract) Call( return nil, fmt.Errorf("invalid transfer params") } - t.GasLimit = uint64(GasLimitPerAuthTransfer * len(transferParams)) + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.AuthorizedTransfer(t, transferParams) case "burn_editions": @@ -165,7 +171,12 @@ func (c *FeralfileExhibitionV3Contract) Call( return nil, fmt.Errorf("invalid token id params") } - t.GasLimit = GasLimitTransfer + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.SafeTransferFrom(t, common.HexToAddress(wallet.Account()), @@ -181,7 +192,12 @@ func (c *FeralfileExhibitionV3Contract) Call( return nil, fmt.Errorf("invalid operator params") } - t.GasLimit = GasLimitApproveForAll + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.SetApprovalForAll(t, operator, true) default: @@ -190,6 +206,7 @@ func (c *FeralfileExhibitionV3Contract) Call( } func (c *FeralfileExhibitionV3Contract) Pack( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]byte, error) { abi, err := feralfilev3.FeralfileExhibitionV3MetaData.GetAbi() @@ -197,15 +214,33 @@ func (c *FeralfileExhibitionV3Contract) Pack( return nil, err } - parsedArgs, err := c.Parse(method, arguments) + parsedArgs, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } + switch method { + case "register_artworks": + method = "createArtworks" + case "mint_editions": + method = "batchMint" + case "authorized_transfer": + method = "authorizedTransfer" + case "burn_editions": + method = "burnEditions" + case "transfer": + method = "safeTransferFrom" + case "approve_for_all": + method = "setApprovalForAll" + default: + return nil, fmt.Errorf("unsupported method") + } + return abi.Pack(method, parsedArgs...) } func (c *FeralfileExhibitionV3Contract) Parse( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]interface{}, error) { switch method { @@ -339,7 +374,7 @@ func (c *FeralfileExhibitionV3Contract) Parse( return nil, err } - return []interface{}{params.To, ¶ms.TokenID.Int}, nil + return []interface{}{common.HexToAddress(wallet.Account()), params.To, ¶ms.TokenID.Int}, nil case "approve_for_all": var params struct { Operator common.Address `json:"operator"` @@ -348,12 +383,35 @@ func (c *FeralfileExhibitionV3Contract) Parse( return nil, err } - return []interface{}{params.Operator}, nil + return []interface{}{params.Operator, true}, nil default: return nil, fmt.Errorf("unsupported method") } } +func (c *FeralfileExhibitionV3Contract) EstimateGasLimit( + wallet *ethereum.Wallet, + contractAddr common.Address, + method string, + arguments json.RawMessage) (uint64, error) { + data, err := c.Pack(wallet, method, arguments) + if nil != err { + return 0, err + } + + gas, err := wallet.RPCClient().EstimateGas(context.Background(), goEthereum.CallMsg{ + From: common.HexToAddress(wallet.Account()), + To: &contractAddr, + Data: data, + }) + + if nil != err { + return 0, err + } + + return gas * 115 / 100, nil // add 15% buffer +} + func init() { ethereum.RegisterContract("FeralfileExhibitionV3", FeralfileExhibitionV3ContractFactory) } diff --git a/contracts/feralfile-exhibition-v4/feralfile.go b/contracts/feralfile-exhibition-v4/feralfile.go index d927069..548c6d5 100644 --- a/contracts/feralfile-exhibition-v4/feralfile.go +++ b/contracts/feralfile-exhibition-v4/feralfile.go @@ -1,6 +1,7 @@ package feralfilev4 import ( + "context" "encoding/hex" "encoding/json" "errors" @@ -9,6 +10,7 @@ import ( "strconv" "strings" + goEthereum "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" @@ -17,12 +19,6 @@ import ( feralfilev4 "github.com/bitmark-inc/feralfile-exhibition-smart-contract/go-binding/feralfile-exhibition-v4" ) -const ( - GasLimitPerMint = 150000 - GasLimitPerBurn = 50000 - GasLimitApproveForAll = 80000 -) - type FeralfileExhibitionV4Contract struct { contractAddress string } @@ -87,7 +83,8 @@ func (c *FeralfileExhibitionV4Contract) Call( noSend bool, customizeGasPriceInWei *int64, customizedNonce *uint64) (*types.Transaction, error) { - contract, err := feralfilev4.NewFeralfileExhibitionV4(common.HexToAddress(c.contractAddress), wallet.RPCClient()) + contractAddr := common.HexToAddress(c.contractAddress) + contract, err := feralfilev4.NewFeralfileExhibitionV4(contractAddr, wallet.RPCClient()) if err != nil { return nil, err } @@ -106,7 +103,7 @@ func (c *FeralfileExhibitionV4Contract) Call( t.Nonce = big.NewInt(int64(*customizedNonce)) } - params, err := c.Parse(method, arguments) + params, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } @@ -122,7 +119,12 @@ func (c *FeralfileExhibitionV4Contract) Call( return nil, errors.New("Invalid token burn parameters") } - t.GasLimit = uint64(GasLimitPerBurn * len(tokenIDs)) + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit * 115 / 100 return contract.BurnArtworks(t, tokenIDs) case "mintArtworks": @@ -135,7 +137,12 @@ func (c *FeralfileExhibitionV4Contract) Call( return nil, errors.New("Invalid token mint parameters") } - t.GasLimit = uint64(GasLimitPerMint * len(mintData)) + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.MintArtworks(t, mintData) case "setTokenBaseURI": @@ -198,7 +205,12 @@ func (c *FeralfileExhibitionV4Contract) Call( return nil, errors.New("Invalid operator") } - t.GasLimit = GasLimitApproveForAll + gasLimit, err := c.EstimateGasLimit(wallet, contractAddr, method, arguments) + if nil != err { + return nil, err + } + + t.GasLimit = gasLimit return contract.SetApprovalForAll(t, operator, true) default: @@ -207,6 +219,7 @@ func (c *FeralfileExhibitionV4Contract) Call( } func (c *FeralfileExhibitionV4Contract) Pack( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]byte, error) { abi, err := feralfilev4.FeralfileExhibitionV4MetaData.GetAbi() @@ -214,15 +227,35 @@ func (c *FeralfileExhibitionV4Contract) Pack( return nil, err } - parsedArgs, err := c.Parse(method, arguments) + parsedArgs, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } + switch method { + case "burnArtworks": + method = "burnArtworks" + case "mintArtworks": + method = "mintArtworks" + case "setTokenBaseURI": + method = "setTokenBaseURI" + case "startSale": + method = "startSale" + case "transferOwnership": + method = "transferOwnership" + case "approve_for_all": + method = "setApprovalForAll" + case "buyArtworks": + method = "buyArtworks" + default: + return nil, fmt.Errorf("unsupported method") + } + return abi.Pack(method, parsedArgs...) } func (c *FeralfileExhibitionV4Contract) Parse( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]interface{}, error) { switch method { @@ -287,7 +320,7 @@ func (c *FeralfileExhibitionV4Contract) Parse( return nil, err } - return []interface{}{params.Operator}, nil + return []interface{}{params.Operator, true}, nil case "buyArtworks": var params struct { SaleData struct { @@ -366,6 +399,29 @@ func (c *FeralfileExhibitionV4Contract) Parse( } } +func (c *FeralfileExhibitionV4Contract) EstimateGasLimit( + wallet *ethereum.Wallet, + contractAddr common.Address, + method string, + arguments json.RawMessage) (uint64, error) { + data, err := c.Pack(wallet, method, arguments) + if nil != err { + return 0, err + } + + gas, err := wallet.RPCClient().EstimateGas(context.Background(), goEthereum.CallMsg{ + From: common.HexToAddress(wallet.Account()), + To: &contractAddr, + Data: data, + }) + + if nil != err { + return 0, err + } + + return gas * 115 / 100, nil // add 15% buffer +} + func init() { ethereum.RegisterContract("FeralfileExhibitionV4", FeralfileExhibitionV4ContractFactory) } diff --git a/contracts/owner-data/ownerdata.go b/contracts/owner-data/ownerdata.go index 384d6d3..f8dc1d9 100644 --- a/contracts/owner-data/ownerdata.go +++ b/contracts/owner-data/ownerdata.go @@ -52,7 +52,7 @@ func (c *OwnerDataContract) Call(wallet *ethereum.Wallet, method, fund string, a t.Nonce = big.NewInt(int64(*customizedNonce)) } - params, err := c.Parse(method, arguments) + params, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } @@ -95,6 +95,7 @@ func (c *OwnerDataContract) Call(wallet *ethereum.Wallet, method, fund string, a } func (c *OwnerDataContract) Pack( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]byte, error) { abi, err := ownerdata.OwnerDataMetaData.GetAbi() @@ -102,7 +103,7 @@ func (c *OwnerDataContract) Pack( return nil, err } - parsedArgs, err := c.Parse(method, arguments) + parsedArgs, err := c.Parse(wallet, method, arguments) if nil != err { return nil, err } @@ -111,6 +112,7 @@ func (c *OwnerDataContract) Pack( } func (c *OwnerDataContract) Parse( + wallet *ethereum.Wallet, method string, arguments json.RawMessage) ([]interface{}, error) { switch method { @@ -179,6 +181,14 @@ func (c *OwnerDataContract) Parse( } } +func (c *OwnerDataContract) EstimateGasLimit( + wallet *ethereum.Wallet, + contractAddr common.Address, + method string, + arguments json.RawMessage) (uint64, error) { + return 0, errors.New("not implemented") +} + func init() { ethereum.RegisterContract("OwnerData", OwnerDataContractFactory) }