mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 01:13:45 +00:00
Merge b43f4783d7 into e9295163aa
This commit is contained in:
commit
d367fe2f18
7 changed files with 43 additions and 36 deletions
|
|
@ -33,6 +33,7 @@ type ABI struct {
|
||||||
Constructor Method
|
Constructor Method
|
||||||
Methods map[string]Method
|
Methods map[string]Method
|
||||||
Events map[string]Event
|
Events map[string]Event
|
||||||
|
Fallback Method
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON returns a parsed ABI interface and error if it failed.
|
// JSON returns a parsed ABI interface and error if it failed.
|
||||||
|
|
@ -185,6 +186,7 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
|
||||||
Constant bool
|
Constant bool
|
||||||
Indexed bool
|
Indexed bool
|
||||||
Anonymous bool
|
Anonymous bool
|
||||||
|
Payable bool
|
||||||
Inputs []Argument
|
Inputs []Argument
|
||||||
Outputs []Argument
|
Outputs []Argument
|
||||||
}
|
}
|
||||||
|
|
@ -201,11 +203,11 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
|
||||||
abi.Constructor = Method{
|
abi.Constructor = Method{
|
||||||
Inputs: field.Inputs,
|
Inputs: field.Inputs,
|
||||||
}
|
}
|
||||||
// empty defaults to function according to the abi spec
|
case "function":
|
||||||
case "function", "":
|
|
||||||
abi.Methods[field.Name] = Method{
|
abi.Methods[field.Name] = Method{
|
||||||
Name: field.Name,
|
Name: field.Name,
|
||||||
Const: field.Constant,
|
Const: field.Constant,
|
||||||
|
Payable: field.Payable,
|
||||||
Inputs: field.Inputs,
|
Inputs: field.Inputs,
|
||||||
Outputs: field.Outputs,
|
Outputs: field.Outputs,
|
||||||
}
|
}
|
||||||
|
|
@ -215,6 +217,12 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
|
||||||
Anonymous: field.Anonymous,
|
Anonymous: field.Anonymous,
|
||||||
Inputs: field.Inputs,
|
Inputs: field.Inputs,
|
||||||
}
|
}
|
||||||
|
case "fallback":
|
||||||
|
abi.Fallback = Method{
|
||||||
|
Payable: field.Payable,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("abi: contract interaction type not referenced")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,8 @@ const jsondata = `
|
||||||
|
|
||||||
const jsondata2 = `
|
const jsondata2 = `
|
||||||
[
|
[
|
||||||
{ "type" : "function", "name" : "balance", "constant" : true },
|
{ "type" : "function", "name" : "balance", "constant" : true, "payable" : false },
|
||||||
{ "type" : "function", "name" : "send", "constant" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] },
|
{ "type" : "function", "name" : "send", "constant" : false, "payable" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] },
|
||||||
{ "type" : "function", "name" : "test", "constant" : false, "inputs" : [ { "name" : "number", "type" : "uint32" } ] },
|
{ "type" : "function", "name" : "test", "constant" : false, "inputs" : [ { "name" : "number", "type" : "uint32" } ] },
|
||||||
{ "type" : "function", "name" : "string", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "string" } ] },
|
{ "type" : "function", "name" : "string", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "string" } ] },
|
||||||
{ "type" : "function", "name" : "bool", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "bool" } ] },
|
{ "type" : "function", "name" : "bool", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "bool" } ] },
|
||||||
|
|
@ -77,10 +77,10 @@ func TestReader(t *testing.T) {
|
||||||
exp := ABI{
|
exp := ABI{
|
||||||
Methods: map[string]Method{
|
Methods: map[string]Method{
|
||||||
"balance": {
|
"balance": {
|
||||||
"balance", true, nil, nil,
|
"balance", false, true, nil, nil,
|
||||||
},
|
},
|
||||||
"send": {
|
"send": {
|
||||||
"send", false, []Argument{
|
"send", false, false, []Argument{
|
||||||
{"amount", Uint256, false},
|
{"amount", Uint256, false},
|
||||||
}, nil,
|
}, nil,
|
||||||
},
|
},
|
||||||
|
|
@ -180,7 +180,7 @@ func TestTestSlice(t *testing.T) {
|
||||||
|
|
||||||
func TestMethodSignature(t *testing.T) {
|
func TestMethodSignature(t *testing.T) {
|
||||||
String, _ := NewType("string")
|
String, _ := NewType("string")
|
||||||
m := Method{"foo", false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil}
|
m := Method{"foo", false, false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil}
|
||||||
exp := "foo(string,string)"
|
exp := "foo(string,string)"
|
||||||
if m.Sig() != exp {
|
if m.Sig() != exp {
|
||||||
t.Error("signature mismatch", exp, "!=", m.Sig())
|
t.Error("signature mismatch", exp, "!=", m.Sig())
|
||||||
|
|
@ -192,7 +192,7 @@ func TestMethodSignature(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uintt, _ := NewType("uint")
|
uintt, _ := NewType("uint")
|
||||||
m = Method{"foo", false, []Argument{{"bar", uintt, false}}, nil}
|
m = Method{"foo", false, false, []Argument{{"bar", uintt, false}}, nil}
|
||||||
exp = "foo(uint256)"
|
exp = "foo(uint256)"
|
||||||
if m.Sig() != exp {
|
if m.Sig() != exp {
|
||||||
t.Error("signature mismatch", exp, "!=", m.Sig())
|
t.Error("signature mismatch", exp, "!=", m.Sig())
|
||||||
|
|
@ -367,19 +367,6 @@ func TestInputVariableInputLength(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaultFunctionParsing(t *testing.T) {
|
|
||||||
const definition = `[{ "name" : "balance" }]`
|
|
||||||
|
|
||||||
abi, err := JSON(strings.NewReader(definition))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := abi.Methods["balance"]; !ok {
|
|
||||||
t.Error("expected 'balance' to be present")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBareEvents(t *testing.T) {
|
func TestBareEvents(t *testing.T) {
|
||||||
const definition = `[
|
const definition = `[
|
||||||
{ "type" : "event", "name" : "balance" },
|
{ "type" : "event", "name" : "balance" },
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,11 @@ func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...in
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// check to make sure method is payable and if not, make sure that there is no
|
||||||
|
// value being transported with this transaction
|
||||||
|
if !c.abi.Methods[method].Payable && 0 != opts.Value.Cmp(common.Big0) {
|
||||||
|
return nil, fmt.Errorf("bind: value %v sent to non payable method %v", opts.Value.String(), method)
|
||||||
|
}
|
||||||
return c.transact(opts, &c.address, input)
|
return c.transact(opts, &c.address, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La
|
||||||
var (
|
var (
|
||||||
calls = make(map[string]*tmplMethod)
|
calls = make(map[string]*tmplMethod)
|
||||||
transacts = make(map[string]*tmplMethod)
|
transacts = make(map[string]*tmplMethod)
|
||||||
|
writes = make(map[string]*tmplMethod)
|
||||||
)
|
)
|
||||||
for _, original := range evmABI.Methods {
|
for _, original := range evmABI.Methods {
|
||||||
// Normalize the method for capital cases and non-anonymous inputs/outputs
|
// Normalize the method for capital cases and non-anonymous inputs/outputs
|
||||||
|
|
@ -90,8 +91,10 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La
|
||||||
// Append the methods to the call or transact lists
|
// Append the methods to the call or transact lists
|
||||||
if original.Const {
|
if original.Const {
|
||||||
calls[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original)}
|
calls[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original)}
|
||||||
} else {
|
} else if original.Payable {
|
||||||
transacts[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original)}
|
transacts[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original)}
|
||||||
|
} else {
|
||||||
|
writes[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contracts[types[i]] = &tmplContract{
|
contracts[types[i]] = &tmplContract{
|
||||||
|
|
@ -99,8 +102,10 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La
|
||||||
InputABI: strings.Replace(strippedABI, "\"", "\\\"", -1),
|
InputABI: strings.Replace(strippedABI, "\"", "\\\"", -1),
|
||||||
InputBin: strings.TrimSpace(bytecodes[i]),
|
InputBin: strings.TrimSpace(bytecodes[i]),
|
||||||
Constructor: evmABI.Constructor,
|
Constructor: evmABI.Constructor,
|
||||||
|
Fallback: evmABI.Fallback,
|
||||||
Calls: calls,
|
Calls: calls,
|
||||||
Transacts: transacts,
|
Transacts: transacts,
|
||||||
|
Writes: writes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Generate the contract template data content and render it
|
// Generate the contract template data content and render it
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ type tmplContract struct {
|
||||||
InputABI string // JSON ABI used as the input to generate the binding from
|
InputABI string // JSON ABI used as the input to generate the binding from
|
||||||
InputBin string // Optional EVM bytecode used to denetare deploy code from
|
InputBin string // Optional EVM bytecode used to denetare deploy code from
|
||||||
Constructor abi.Method // Contract constructor for deploy parametrization
|
Constructor abi.Method // Contract constructor for deploy parametrization
|
||||||
|
Fallback abi.Method // Contract fallback method for direct interaction with contract
|
||||||
Calls map[string]*tmplMethod // Contract calls that only read state data
|
Calls map[string]*tmplMethod // Contract calls that only read state data
|
||||||
Transacts map[string]*tmplMethod // Contract calls that write state data
|
Transacts map[string]*tmplMethod // Contract calls that write state data
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
// Input specifies the required input parameters for this gives method.
|
// Input specifies the required input parameters for this gives method.
|
||||||
type Method struct {
|
type Method struct {
|
||||||
Name string
|
Name string
|
||||||
|
Payable bool
|
||||||
Const bool
|
Const bool
|
||||||
Inputs []Argument
|
Inputs []Argument
|
||||||
Outputs []Argument
|
Outputs []Argument
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ func TestSimpleMethodUnpack(t *testing.T) {
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
abiDefinition := fmt.Sprintf(`[{ "name" : "method", "outputs": %s}]`, test.def)
|
abiDefinition := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def)
|
||||||
abi, err := JSON(strings.NewReader(abiDefinition))
|
abi, err := JSON(strings.NewReader(abiDefinition))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d failed. %v", i, err)
|
t.Errorf("%d failed. %v", i, err)
|
||||||
|
|
@ -286,7 +286,7 @@ func TestUnpackSetInterfaceArrayOutput(t *testing.T) {
|
||||||
|
|
||||||
func TestMultiReturnWithStruct(t *testing.T) {
|
func TestMultiReturnWithStruct(t *testing.T) {
|
||||||
const definition = `[
|
const definition = `[
|
||||||
{ "name" : "multi", "constant" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
|
{ "name" : "multi", "type": "function", "constant" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
|
||||||
|
|
||||||
abi, err := JSON(strings.NewReader(definition))
|
abi, err := JSON(strings.NewReader(definition))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -339,7 +339,7 @@ func TestMultiReturnWithStruct(t *testing.T) {
|
||||||
|
|
||||||
func TestMultiReturnWithSlice(t *testing.T) {
|
func TestMultiReturnWithSlice(t *testing.T) {
|
||||||
const definition = `[
|
const definition = `[
|
||||||
{ "name" : "multi", "constant" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
|
{ "name" : "multi", "type": "function", "constant" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
|
||||||
|
|
||||||
abi, err := JSON(strings.NewReader(definition))
|
abi, err := JSON(strings.NewReader(definition))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -375,8 +375,8 @@ func TestMultiReturnWithSlice(t *testing.T) {
|
||||||
|
|
||||||
func TestMarshalArrays(t *testing.T) {
|
func TestMarshalArrays(t *testing.T) {
|
||||||
const definition = `[
|
const definition = `[
|
||||||
{ "name" : "bytes32", "constant" : false, "outputs": [ { "type": "bytes32" } ] },
|
{ "name" : "bytes32", "type": "function", "constant" : false, "outputs": [ { "type": "bytes32" } ] },
|
||||||
{ "name" : "bytes10", "constant" : false, "outputs": [ { "type": "bytes10" } ] }
|
{ "name" : "bytes10", "type": "function", "constant" : false, "outputs": [ { "type": "bytes10" } ] }
|
||||||
]`
|
]`
|
||||||
|
|
||||||
abi, err := JSON(strings.NewReader(definition))
|
abi, err := JSON(strings.NewReader(definition))
|
||||||
|
|
@ -434,15 +434,15 @@ func TestMarshalArrays(t *testing.T) {
|
||||||
|
|
||||||
func TestUnmarshal(t *testing.T) {
|
func TestUnmarshal(t *testing.T) {
|
||||||
const definition = `[
|
const definition = `[
|
||||||
{ "name" : "int", "constant" : false, "outputs": [ { "type": "uint256" } ] },
|
{ "name" : "int", "type": "function", "constant" : false, "outputs": [ { "type": "uint256" } ] },
|
||||||
{ "name" : "bool", "constant" : false, "outputs": [ { "type": "bool" } ] },
|
{ "name" : "bool", "type": "function", "constant" : false, "outputs": [ { "type": "bool" } ] },
|
||||||
{ "name" : "bytes", "constant" : false, "outputs": [ { "type": "bytes" } ] },
|
{ "name" : "bytes", "type": "function", "constant" : false, "outputs": [ { "type": "bytes" } ] },
|
||||||
{ "name" : "fixed", "constant" : false, "outputs": [ { "type": "bytes32" } ] },
|
{ "name" : "fixed", "type": "function", "constant" : false, "outputs": [ { "type": "bytes32" } ] },
|
||||||
{ "name" : "multi", "constant" : false, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] },
|
{ "name" : "multi", "type": "function", "constant" : false, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] },
|
||||||
{ "name" : "intArraySingle", "constant" : false, "outputs": [ { "type": "uint256[3]" } ] },
|
{ "name" : "intArraySingle", "type": "function", "constant" : false, "outputs": [ { "type": "uint256[3]" } ] },
|
||||||
{ "name" : "addressSliceSingle", "constant" : false, "outputs": [ { "type": "address[]" } ] },
|
{ "name" : "addressSliceSingle", "type": "function", "constant" : false, "outputs": [ { "type": "address[]" } ] },
|
||||||
{ "name" : "addressSliceDouble", "constant" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
|
{ "name" : "addressSliceDouble", "type": "function", "constant" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
|
||||||
{ "name" : "mixedBytes", "constant" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]`
|
{ "name" : "mixedBytes", "type": "function", "constant" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]`
|
||||||
|
|
||||||
abi, err := JSON(strings.NewReader(definition))
|
abi, err := JSON(strings.NewReader(definition))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue