forked from cerc-io/plugeth
accounts/abi/bind: Accept function ptr parameter (#19755)
* accounts/abi/bind: Accept function ptr parameter They are translated as [24]byte * Add Java template version * accounts/abi/bind: fix merge issue * Fix CI
This commit is contained in:
parent
0b26a826e9
commit
6bf5555c4f
@ -44,7 +44,7 @@ const (
|
|||||||
// to be used as is in client code, but rather as an intermediate struct which
|
// to be used as is in client code, but rather as an intermediate struct which
|
||||||
// enforces compile time type safety and naming convention opposed to having to
|
// enforces compile time type safety and naming convention opposed to having to
|
||||||
// manually maintain hard coded strings that break on runtime.
|
// manually maintain hard coded strings that break on runtime.
|
||||||
func Bind(types []string, abis []string, bytecodes []string, pkg string, lang Lang) (string, error) {
|
func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang) (string, error) {
|
||||||
// Process each individual contract requested binding
|
// Process each individual contract requested binding
|
||||||
contracts := make(map[string]*tmplContract)
|
contracts := make(map[string]*tmplContract)
|
||||||
|
|
||||||
@ -125,6 +125,9 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La
|
|||||||
Transacts: transacts,
|
Transacts: transacts,
|
||||||
Events: events,
|
Events: events,
|
||||||
}
|
}
|
||||||
|
if len(fsigs) > i {
|
||||||
|
contracts[types[i]].FuncSigs = fsigs[i]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Generate the contract template data content and render it
|
// Generate the contract template data content and render it
|
||||||
data := &tmplData{
|
data := &tmplData{
|
||||||
@ -180,8 +183,7 @@ func bindBasicTypeGo(kind abi.Type) string {
|
|||||||
case abi.BytesTy:
|
case abi.BytesTy:
|
||||||
return "[]byte"
|
return "[]byte"
|
||||||
case abi.FunctionTy:
|
case abi.FunctionTy:
|
||||||
// todo(rjl493456442)
|
return "[24]byte"
|
||||||
return ""
|
|
||||||
default:
|
default:
|
||||||
// string, bool types
|
// string, bool types
|
||||||
return kind.String()
|
return kind.String()
|
||||||
@ -240,8 +242,7 @@ func bindBasicTypeJava(kind abi.Type) string {
|
|||||||
case abi.StringTy:
|
case abi.StringTy:
|
||||||
return "String"
|
return "String"
|
||||||
case abi.FunctionTy:
|
case abi.FunctionTy:
|
||||||
// todo(rjl493456442)
|
return "byte[24]"
|
||||||
return ""
|
|
||||||
default:
|
default:
|
||||||
return kind.String()
|
return kind.String()
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ var bindTests = []struct {
|
|||||||
abi string
|
abi string
|
||||||
imports string
|
imports string
|
||||||
tester string
|
tester string
|
||||||
|
fsigs []map[string]string
|
||||||
}{
|
}{
|
||||||
// Test that the binding is available in combined and separate forms too
|
// Test that the binding is available in combined and separate forms too
|
||||||
{
|
{
|
||||||
@ -55,6 +56,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("transactor binding (%v) nil or error (%v) not nil", b, nil)
|
t.Fatalf("transactor binding (%v) nil or error (%v) not nil", b, nil)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Test that all the official sample contracts bind correctly
|
// Test that all the official sample contracts bind correctly
|
||||||
{
|
{
|
||||||
@ -68,6 +70,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
|
t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`Crowdsale`,
|
`Crowdsale`,
|
||||||
@ -80,6 +83,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
|
t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`DAO`,
|
`DAO`,
|
||||||
@ -92,6 +96,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
|
t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Test that named and anonymous inputs are handled correctly
|
// Test that named and anonymous inputs are handled correctly
|
||||||
{
|
{
|
||||||
@ -125,6 +130,7 @@ var bindTests = []struct {
|
|||||||
|
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}`,
|
}`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Test that named and anonymous outputs are handled correctly
|
// Test that named and anonymous outputs are handled correctly
|
||||||
{
|
{
|
||||||
@ -161,6 +167,7 @@ var bindTests = []struct {
|
|||||||
|
|
||||||
fmt.Println(str1, str2, res.Str1, res.Str2, err)
|
fmt.Println(str1, str2, res.Str1, res.Str2, err)
|
||||||
}`,
|
}`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Tests that named, anonymous and indexed events are handled correctly
|
// Tests that named, anonymous and indexed events are handled correctly
|
||||||
{
|
{
|
||||||
@ -226,6 +233,7 @@ var bindTests = []struct {
|
|||||||
if _, ok := reflect.TypeOf(&EventChecker{}).MethodByName("FilterAnonymous"); ok {
|
if _, ok := reflect.TypeOf(&EventChecker{}).MethodByName("FilterAnonymous"); ok {
|
||||||
t.Errorf("binding has disallowed method (FilterAnonymous)")
|
t.Errorf("binding has disallowed method (FilterAnonymous)")
|
||||||
}`,
|
}`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Test that contract interactions (deploy, transact and call) generate working code
|
// Test that contract interactions (deploy, transact and call) generate working code
|
||||||
{
|
{
|
||||||
@ -282,6 +290,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("Transact string mismatch: have '%s', want 'Transact string'", str)
|
t.Fatalf("Transact string mismatch: have '%s', want 'Transact string'", str)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Tests that plain values can be properly returned and deserialized
|
// Tests that plain values can be properly returned and deserialized
|
||||||
{
|
{
|
||||||
@ -322,6 +331,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("Retrieved value mismatch: have %v/%v, want %v/%v", str, num, "Hi", 1)
|
t.Fatalf("Retrieved value mismatch: have %v/%v, want %v/%v", str, num, "Hi", 1)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Tests that tuples can be properly returned and deserialized
|
// Tests that tuples can be properly returned and deserialized
|
||||||
{
|
{
|
||||||
@ -362,6 +372,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("Retrieved value mismatch: have %v/%v, want %v/%v", res.A, res.B, "Hi", 1)
|
t.Fatalf("Retrieved value mismatch: have %v/%v, want %v/%v", res.A, res.B, "Hi", 1)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Tests that arrays/slices can be properly returned and deserialized.
|
// Tests that arrays/slices can be properly returned and deserialized.
|
||||||
// Only addresses are tested, remainder just compiled to keep the test small.
|
// Only addresses are tested, remainder just compiled to keep the test small.
|
||||||
@ -414,6 +425,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("Slice return mismatch: have %v, want %v", out, []common.Address{auth.From, common.Address{}})
|
t.Fatalf("Slice return mismatch: have %v, want %v", out, []common.Address{auth.From, common.Address{}})
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Tests that anonymous default methods can be correctly invoked
|
// Tests that anonymous default methods can be correctly invoked
|
||||||
{
|
{
|
||||||
@ -459,6 +471,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("Address mismatch: have %v, want %v", caller, auth.From)
|
t.Fatalf("Address mismatch: have %v, want %v", caller, auth.From)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Tests that non-existent contracts are reported as such (though only simulator test)
|
// Tests that non-existent contracts are reported as such (though only simulator test)
|
||||||
{
|
{
|
||||||
@ -493,6 +506,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("Error mismatch: have %v, want %v", err, bind.ErrNoCode)
|
t.Fatalf("Error mismatch: have %v, want %v", err, bind.ErrNoCode)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Tests that gas estimation works for contracts with weird gas mechanics too.
|
// Tests that gas estimation works for contracts with weird gas mechanics too.
|
||||||
{
|
{
|
||||||
@ -543,6 +557,7 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("Field mismatch: have %v, want %v", field, "automatic")
|
t.Fatalf("Field mismatch: have %v, want %v", field, "automatic")
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Test that constant functions can be called from an (optional) specified address
|
// Test that constant functions can be called from an (optional) specified address
|
||||||
{
|
{
|
||||||
@ -591,6 +606,7 @@ var bindTests = []struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Tests that methods and returns with underscores inside work correctly.
|
// Tests that methods and returns with underscores inside work correctly.
|
||||||
{
|
{
|
||||||
@ -665,6 +681,7 @@ var bindTests = []struct {
|
|||||||
|
|
||||||
fmt.Println(a, b, err)
|
fmt.Println(a, b, err)
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
// Tests that logs can be successfully filtered and decoded.
|
// Tests that logs can be successfully filtered and decoded.
|
||||||
{
|
{
|
||||||
@ -881,6 +898,7 @@ var bindTests = []struct {
|
|||||||
case <-time.After(250 * time.Millisecond):
|
case <-time.After(250 * time.Millisecond):
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`DeeplyNestedArray`,
|
`DeeplyNestedArray`,
|
||||||
@ -956,6 +974,46 @@ var bindTests = []struct {
|
|||||||
t.Fatalf("Retrieved value does not match expected value! got: %d, expected: %d. %v", retrievedArr[4][3][2], testArr[4][3][2], err)
|
t.Fatalf("Retrieved value does not match expected value! got: %d, expected: %d. %v", retrievedArr[4][3][2], testArr[4][3][2], err)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`CallbackParam`,
|
||||||
|
`
|
||||||
|
contract FunctionPointerTest {
|
||||||
|
function test(function(uint256) external callback) external {
|
||||||
|
callback(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
`608060405234801561001057600080fd5b5061015e806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063d7a5aba214610040575b600080fd5b34801561004c57600080fd5b506100be6004803603602081101561006357600080fd5b810190808035806c0100000000000000000000000090049068010000000000000000900463ffffffff1677ffffffffffffffffffffffffffffffffffffffffffffffff169091602001919093929190939291905050506100c0565b005b818160016040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561011657600080fd5b505af115801561012a573d6000803e3d6000fd5b50505050505056fea165627a7a7230582062f87455ff84be90896dbb0c4e4ddb505c600d23089f8e80a512548440d7e2580029`,
|
||||||
|
`[
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "callback",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "test",
|
||||||
|
"outputs": [],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
]`, `
|
||||||
|
"strings"
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
if strings.Compare("test(function)", CallbackParamFuncSigs["d7a5aba2"]) != 0 {
|
||||||
|
t.Fatalf("")
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
[]map[string]string{
|
||||||
|
{
|
||||||
|
"test(function)": "d7a5aba2",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,7 +1039,7 @@ func TestGolangBindings(t *testing.T) {
|
|||||||
// Generate the test suite for all the contracts
|
// Generate the test suite for all the contracts
|
||||||
for i, tt := range bindTests {
|
for i, tt := range bindTests {
|
||||||
// Generate the binding and create a Go source file in the workspace
|
// Generate the binding and create a Go source file in the workspace
|
||||||
bind, err := Bind([]string{tt.name}, []string{tt.abi}, []string{tt.bytecode}, "bindtest", LangGo)
|
bind, err := Bind([]string{tt.name}, []string{tt.abi}, []string{tt.bytecode}, tt.fsigs, "bindtest", LangGo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("test %d: failed to generate binding: %v", i, err)
|
t.Fatalf("test %d: failed to generate binding: %v", i, err)
|
||||||
}
|
}
|
||||||
@ -1072,6 +1130,7 @@ func TestJavaBindings(t *testing.T) {
|
|||||||
package bindtest;
|
package bindtest;
|
||||||
|
|
||||||
import org.ethereum.geth.*;
|
import org.ethereum.geth.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
public class Test {
|
public class Test {
|
||||||
@ -1400,7 +1459,7 @@ public class Test {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, c := range cases {
|
for i, c := range cases {
|
||||||
binding, err := Bind([]string{c.name}, []string{c.abi}, []string{c.bytecode}, "bindtest", LangJava)
|
binding, err := Bind([]string{c.name}, []string{c.abi}, []string{c.bytecode}, nil, "bindtest", LangJava)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("test %d: failed to generate binding: %v", i, err)
|
t.Fatalf("test %d: failed to generate binding: %v", i, err)
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ type tmplContract struct {
|
|||||||
Type string // Type name of the main contract binding
|
Type string // Type name of the main contract binding
|
||||||
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
|
||||||
|
FuncSigs map[string]string // Optional map: string signature -> 4-byte signature
|
||||||
Constructor abi.Method // Contract constructor for deploy parametrization
|
Constructor abi.Method // Contract constructor for deploy parametrization
|
||||||
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
|
||||||
@ -92,6 +93,15 @@ var (
|
|||||||
// {{.Type}}ABI is the input ABI used to generate the binding from.
|
// {{.Type}}ABI is the input ABI used to generate the binding from.
|
||||||
const {{.Type}}ABI = "{{.InputABI}}"
|
const {{.Type}}ABI = "{{.InputABI}}"
|
||||||
|
|
||||||
|
{{if $contract.FuncSigs}}
|
||||||
|
// {{.Type}}FuncSigs maps the 4-byte function signature to its string representation.
|
||||||
|
var {{.Type}}FuncSigs = map[string]string{
|
||||||
|
{{range $strsig, $binsig := .FuncSigs}}
|
||||||
|
"{{$binsig}}": "{{$strsig}}",
|
||||||
|
{{end}}
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
{{if .InputBin}}
|
{{if .InputBin}}
|
||||||
// {{.Type}}Bin is the compiled bytecode used for deploying new contracts.
|
// {{.Type}}Bin is the compiled bytecode used for deploying new contracts.
|
||||||
const {{.Type}}Bin = ` + "`" + `{{.InputBin}}` + "`" + `
|
const {{.Type}}Bin = ` + "`" + `{{.InputBin}}` + "`" + `
|
||||||
@ -464,12 +474,23 @@ const tmplSourceJava = `
|
|||||||
package {{.Package}};
|
package {{.Package}};
|
||||||
|
|
||||||
import org.ethereum.geth.*;
|
import org.ethereum.geth.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
{{range $contract := .Contracts}}
|
{{range $contract := .Contracts}}
|
||||||
public class {{.Type}} {
|
public class {{.Type}} {
|
||||||
// ABI is the input ABI used to generate the binding from.
|
// ABI is the input ABI used to generate the binding from.
|
||||||
public final static String ABI = "{{.InputABI}}";
|
public final static String ABI = "{{.InputABI}}";
|
||||||
|
{{if $contract.FuncSigs}}
|
||||||
|
// {{.Type}}FuncSigs maps the 4-byte function signature to its string representation.
|
||||||
|
public final static Map<String, String> {{.Type}}FuncSigs;
|
||||||
|
static {
|
||||||
|
Hashtable<String, String> temp = new Hashtable<String, String>();
|
||||||
|
{{range $strsig, $binsig := .FuncSigs}}
|
||||||
|
temp.put("{{$binsig}}", "{{$strsig}}");
|
||||||
|
{{end}}
|
||||||
|
{{.Type}}FuncSigs = Collections.unmodifiableMap(temp);
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
{{if .InputBin}}
|
{{if .InputBin}}
|
||||||
// BYTECODE is the compiled bytecode used for deploying new contracts.
|
// BYTECODE is the compiled bytecode used for deploying new contracts.
|
||||||
public final static String BYTECODE = "0x{{.InputBin}}";
|
public final static String BYTECODE = "0x{{.InputBin}}";
|
||||||
|
@ -78,6 +78,7 @@ func main() {
|
|||||||
abis []string
|
abis []string
|
||||||
bins []string
|
bins []string
|
||||||
types []string
|
types []string
|
||||||
|
sigs []map[string]string
|
||||||
)
|
)
|
||||||
if *solFlag != "" || *vyFlag != "" || *abiFlag == "-" {
|
if *solFlag != "" || *vyFlag != "" || *abiFlag == "-" {
|
||||||
// Generate the list of types to exclude from binding
|
// Generate the list of types to exclude from binding
|
||||||
@ -121,6 +122,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
abis = append(abis, string(abi))
|
abis = append(abis, string(abi))
|
||||||
bins = append(bins, contract.Code)
|
bins = append(bins, contract.Code)
|
||||||
|
sigs = append(sigs, contract.Hashes)
|
||||||
|
|
||||||
nameParts := strings.Split(name, ":")
|
nameParts := strings.Split(name, ":")
|
||||||
types = append(types, nameParts[len(nameParts)-1])
|
types = append(types, nameParts[len(nameParts)-1])
|
||||||
@ -151,7 +153,7 @@ func main() {
|
|||||||
types = append(types, kind)
|
types = append(types, kind)
|
||||||
}
|
}
|
||||||
// Generate the contract binding
|
// Generate the contract binding
|
||||||
code, err := bind.Bind(types, abis, bins, *pkgFlag, lang)
|
code, err := bind.Bind(types, abis, bins, sigs, *pkgFlag, lang)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to generate ABI binding: %v\n", err)
|
fmt.Printf("Failed to generate ABI binding: %v\n", err)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
|
@ -30,6 +30,7 @@ type Contract struct {
|
|||||||
Code string `json:"code"`
|
Code string `json:"code"`
|
||||||
RuntimeCode string `json:"runtime-code"`
|
RuntimeCode string `json:"runtime-code"`
|
||||||
Info ContractInfo `json:"info"`
|
Info ContractInfo `json:"info"`
|
||||||
|
Hashes map[string]string `json:"hashes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContractInfo contains information about a compiled contract, including access
|
// ContractInfo contains information about a compiled contract, including access
|
||||||
|
@ -39,6 +39,7 @@ type solcOutput struct {
|
|||||||
BinRuntime string `json:"bin-runtime"`
|
BinRuntime string `json:"bin-runtime"`
|
||||||
SrcMapRuntime string `json:"srcmap-runtime"`
|
SrcMapRuntime string `json:"srcmap-runtime"`
|
||||||
Bin, SrcMap, Abi, Devdoc, Userdoc, Metadata string
|
Bin, SrcMap, Abi, Devdoc, Userdoc, Metadata string
|
||||||
|
Hashes map[string]string
|
||||||
}
|
}
|
||||||
Version string
|
Version string
|
||||||
}
|
}
|
||||||
@ -49,7 +50,7 @@ func (s *Solidity) makeArgs() []string {
|
|||||||
"--optimize", // code optimizer switched on
|
"--optimize", // code optimizer switched on
|
||||||
}
|
}
|
||||||
if s.Major > 0 || s.Minor > 4 || s.Patch > 6 {
|
if s.Major > 0 || s.Minor > 4 || s.Patch > 6 {
|
||||||
p[1] += ",metadata"
|
p[1] += ",metadata,hashes"
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
@ -161,6 +162,7 @@ func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion strin
|
|||||||
contracts[name] = &Contract{
|
contracts[name] = &Contract{
|
||||||
Code: "0x" + info.Bin,
|
Code: "0x" + info.Bin,
|
||||||
RuntimeCode: "0x" + info.BinRuntime,
|
RuntimeCode: "0x" + info.BinRuntime,
|
||||||
|
Hashes: info.Hashes,
|
||||||
Info: ContractInfo{
|
Info: ContractInfo{
|
||||||
Source: source,
|
Source: source,
|
||||||
Language: "Solidity",
|
Language: "Solidity",
|
||||||
|
Loading…
Reference in New Issue
Block a user