accounts/abi: fix method constant flag for solidity 6.0 (#20482)

This commit is contained in:
Sylvain Laurent 2020-01-06 12:03:26 +01:00 committed by Felix Lange
parent 3bb6815fc1
commit b7cf41e4b3
2 changed files with 64 additions and 7 deletions

View File

@ -108,12 +108,13 @@ func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte)
// UnmarshalJSON implements json.Unmarshaler interface // UnmarshalJSON implements json.Unmarshaler interface
func (abi *ABI) UnmarshalJSON(data []byte) error { func (abi *ABI) UnmarshalJSON(data []byte) error {
var fields []struct { var fields []struct {
Type string Type string
Name string Name string
Constant bool Constant bool
Anonymous bool StateMutability string
Inputs []Argument Anonymous bool
Outputs []Argument Inputs []Argument
Outputs []Argument
} }
if err := json.Unmarshal(data, &fields); err != nil { if err := json.Unmarshal(data, &fields); err != nil {
return err return err
@ -134,10 +135,11 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
name = fmt.Sprintf("%s%d", field.Name, idx) name = fmt.Sprintf("%s%d", field.Name, idx)
_, ok = abi.Methods[name] _, ok = abi.Methods[name]
} }
isConst := field.Constant || field.StateMutability == "pure" || field.StateMutability == "view"
abi.Methods[name] = Method{ abi.Methods[name] = Method{
Name: name, Name: name,
RawName: field.Name, RawName: field.Name,
Const: field.Constant, Const: isConst,
Inputs: field.Inputs, Inputs: field.Inputs,
Outputs: field.Outputs, Outputs: field.Outputs,
} }

View File

@ -1530,6 +1530,61 @@ var bindTests = []struct {
nil, nil,
[]string{"ContractOne", "ContractTwo", "ExternalLib"}, []string{"ContractOne", "ContractTwo", "ExternalLib"},
}, },
// Test the existence of the free retrieval calls
{
`PureAndView`,
`pragma solidity >=0.6.0;
contract PureAndView {
function PureFunc() public pure returns (uint) {
return 42;
}
function ViewFunc() public view returns (uint) {
return block.number;
}
}
`,
[]string{`608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806376b5686a146037578063bb38c66c146053575b600080fd5b603d606f565b6040518082815260200191505060405180910390f35b60596077565b6040518082815260200191505060405180910390f35b600043905090565b6000602a90509056fea2646970667358221220d158c2ab7fdfce366a7998ec79ab84edd43b9815630bbaede2c760ea77f29f7f64736f6c63430006000033`},
[]string{`[{"inputs": [],"name": "PureFunc","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "ViewFunc","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"}]`},
`
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
`,
`
// Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key)
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close()
// Deploy a tester contract and execute a structured call on it
_, _, pav, err := DeployPureAndView(auth, sim)
if err != nil {
t.Fatalf("Failed to deploy PureAndView contract: %v", err)
}
sim.Commit()
// This test the existence of the free retreiver call for view and pure functions
if num, err := pav.PureFunc(nil); err != nil {
t.Fatalf("Failed to call anonymous field retriever: %v", err)
} else if num.Cmp(big.NewInt(42)) != 0 {
t.Fatalf("Retrieved value mismatch: have %v, want %v", num, 42)
}
if num, err := pav.ViewFunc(nil); err != nil {
t.Fatalf("Failed to call anonymous field retriever: %v", err)
} else if num.Cmp(big.NewInt(1)) != 0 {
t.Fatalf("Retrieved value mismatch: have %v, want %v", num, 1)
}
`,
nil,
nil,
nil,
nil,
},
} }
// Tests that packages generated by the binder can be successfully compiled and // Tests that packages generated by the binder can be successfully compiled and