diff --git a/accounts/abi/type2.go b/accounts/abi/type2.go index 4c3b1d10d..2ff4c6c42 100644 --- a/accounts/abi/type2.go +++ b/accounts/abi/type2.go @@ -21,10 +21,8 @@ func (t Type) Pack(v interface{}) ([]byte, error) { return t.pack(reflect.ValueOf(v)) } -func (t Type) Unpack(data []byte, obj interface{}) error { - fmt.Println(toGoType(0, t, data)) - - return nil +func (t Type) Unpack(data []byte) (interface{}, error) { + return toGoType(0, t, data) } // newTypeForTuple implements the format described in https://blog.ricmoo.com/human-readable-contract-abis-in-ethers-js-141902f4d917 @@ -76,6 +74,11 @@ func newTypeForTuple(s string) (string, []ArgumentMarshaling, error) { } } + if len(fields) == 1 && fields[0] == "" { + // empty tuple (i.e. tuple()) + fields = []string{} + } + // trim the args of spaces for i := range fields { fields[i] = strings.TrimSpace(fields[i]) @@ -83,18 +86,21 @@ func newTypeForTuple(s string) (string, []ArgumentMarshaling, error) { // decode the type of each field var args []ArgumentMarshaling - for _, field := range fields { + for indx, field := range fields { // anonymous fields are not supported so the first // string should be the identifier of the field. + var name string spacePos := strings.Index(field, " ") if spacePos == -1 { - return "", nil, fmt.Errorf("invalid tuple field name not found '%s'", field) + // it has no name + name = fmt.Sprintf("arg%d", indx) + } else { + // it has name and field (name field) + name = field[:spacePos] + field = field[spacePos+1:] } - name := field[:spacePos] - field = field[spacePos+1:] - if strings.HasPrefix(field, "tuple") { // decode a recursive tuple sig, elems, err := newTypeForTuple(field) diff --git a/accounts/abi/type2_test.go b/accounts/abi/type2_test.go index 2dd7e1cef..1daec9174 100644 --- a/accounts/abi/type2_test.go +++ b/accounts/abi/type2_test.go @@ -40,15 +40,22 @@ func TestNewType2FromString(t *testing.T) { }{A: 1, B: 2}, }, { - "tuple(a uint64, b tuple(c uint64), d uint64)", + // empty tuple + "tuple()", + "()", + &struct{}{}, + }, + { + // anonymous type + "tuple(uint64,tuple(uint64),uint64)", "(uint64,(uint64),uint64)", &struct { - A uint64 - B struct { - C uint64 + Arg0 uint64 + Arg1 struct { + Arg0 uint64 } - D uint64 - }{A: 1, B: struct{ C uint64 }{C: 2}, D: 3}, + Arg2 uint64 + }{Arg0: 1, Arg1: struct{ Arg0 uint64 }{Arg0: 2}, Arg2: 3}, }, { "tuple(a uint64, b tuple[](x tuple(c uint64), d uint64), e tuple(f uint64, g uint64))", diff --git a/core/vm/contracts_suave.go b/core/vm/contracts_suave.go index fd29e2c4b..d8a9a956e 100644 --- a/core/vm/contracts_suave.go +++ b/core/vm/contracts_suave.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/suave/consolelog" suave "github.com/ethereum/go-ethereum/suave/core" ) @@ -149,6 +150,18 @@ type suaveRuntime struct { var _ SuaveRuntime = &suaveRuntime{} +type consoleLogPrecompile struct { +} + +func (c *consoleLogPrecompile) RequiredGas(input []byte) uint64 { + return 0 +} + +func (c *consoleLogPrecompile) Run(input []byte) ([]byte, error) { + consolelog.Print(input) + return nil, nil +} + func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error) { if request.Method != "GET" && request.Method != "POST" { return nil, fmt.Errorf("only GET and POST methods are supported") diff --git a/core/vm/evm.go b/core/vm/evm.go index a0e773a93..b66678231 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -23,6 +23,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/suave/consolelog" "github.com/holiman/uint256" ) @@ -43,6 +44,11 @@ type ( func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { // First check confidential precompiles, only then continue to the regular ones if evm.chainRules.IsSuave { + // console-log precompile available in the suave context + if addr == consolelog.Console2ContractAddr { + return &consoleLogPrecompile{}, true + } + if isPrecompileAddr(addr) && evm.Config.IsConfidential { suaveContext := NewRuntimeSuaveContext(evm, addr) return NewSuavePrecompiledContractWrapper(addr, suaveContext), true diff --git a/suave/consolelog/console2.json b/suave/consolelog/console2.json new file mode 100644 index 000000000..83727bc98 --- /dev/null +++ b/suave/consolelog/console2.json @@ -0,0 +1,383 @@ +{ + "log()": "51973ec9", + "log(address)": "2c2ecbc2", + "log(address,address)": "daf0d4aa", + "log(address,address,address)": "018c84c2", + "log(address,address,address,address)": "665bf134", + "log(address,address,address,bool)": "0e378994", + "log(address,address,address,string)": "f808da20", + "log(address,address,address,uint256)": "94250d77", + "log(address,address,bool)": "f2a66286", + "log(address,address,bool,address)": "9f1bc36e", + "log(address,address,bool,bool)": "2cd4134a", + "log(address,address,bool,string)": "aa6540c8", + "log(address,address,bool,uint256)": "3971e78c", + "log(address,address,string)": "007150be", + "log(address,address,string,address)": "8f736d16", + "log(address,address,string,bool)": "6f1a594e", + "log(address,address,string,string)": "21bdaf25", + "log(address,address,string,uint256)": "ef1cefe7", + "log(address,address,uint256)": "17fe6185", + "log(address,address,uint256,address)": "8da6def5", + "log(address,address,uint256,bool)": "9b4254e2", + "log(address,address,uint256,string)": "fdb4f990", + "log(address,address,uint256,uint256)": "be553481", + "log(address,bool)": "75b605d3", + "log(address,bool,address)": "f11699ed", + "log(address,bool,address,address)": "660375dd", + "log(address,bool,address,bool)": "a6f50b0f", + "log(address,bool,address,string)": "2dd778e6", + "log(address,bool,address,uint256)": "a75c59de", + "log(address,bool,bool)": "eb830c92", + "log(address,bool,bool,address)": "cf394485", + "log(address,bool,bool,bool)": "cac43479", + "log(address,bool,bool,string)": "dfc4a2e8", + "log(address,bool,bool,uint256)": "8c4e5de6", + "log(address,bool,string)": "212255cc", + "log(address,bool,string,address)": "19fd4956", + "log(address,bool,string,bool)": "50ad461d", + "log(address,bool,string,string)": "475c5c33", + "log(address,bool,string,uint256)": "80e6a20b", + "log(address,bool,uint256)": "9c4f99fb", + "log(address,bool,uint256,address)": "ccf790a1", + "log(address,bool,uint256,bool)": "c4643e20", + "log(address,bool,uint256,string)": "0aa6cfad", + "log(address,bool,uint256,uint256)": "386ff5f4", + "log(address,string)": "759f86bb", + "log(address,string,address)": "f08744e8", + "log(address,string,address,address)": "0d36fa20", + "log(address,string,address,bool)": "0df12b76", + "log(address,string,address,string)": "f7e36245", + "log(address,string,address,uint256)": "457fe3cf", + "log(address,string,bool)": "cf020fb1", + "log(address,string,bool,address)": "205871c2", + "log(address,string,bool,bool)": "5f1d5c9f", + "log(address,string,bool,string)": "bc0b61fe", + "log(address,string,bool,uint256)": "515e38b6", + "log(address,string,string)": "fb772265", + "log(address,string,string,address)": "a04e2f87", + "log(address,string,string,bool)": "35a5071f", + "log(address,string,string,string)": "5d02c50b", + "log(address,string,string,uint256)": "159f8927", + "log(address,string,uint256)": "67dd6ff1", + "log(address,string,uint256,address)": "63183678", + "log(address,string,uint256,bool)": "0ef7e050", + "log(address,string,uint256,string)": "448830a8", + "log(address,string,uint256,uint256)": "1dc8e1b8", + "log(address,uint256)": "8309e8a8", + "log(address,uint256,address)": "7bc0d848", + "log(address,uint256,address,address)": "478d1c62", + "log(address,uint256,address,bool)": "a1bcc9b3", + "log(address,uint256,address,string)": "1da986ea", + "log(address,uint256,address,uint256)": "100f650e", + "log(address,uint256,bool)": "678209a8", + "log(address,uint256,bool,address)": "a31bfdcc", + "log(address,uint256,bool,bool)": "3bf5e537", + "log(address,uint256,bool,string)": "c5ad85f9", + "log(address,uint256,bool,uint256)": "22f6b999", + "log(address,uint256,string)": "a1f2e8aa", + "log(address,uint256,string,address)": "5c430d47", + "log(address,uint256,string,bool)": "cf18105c", + "log(address,uint256,string,string)": "88a8c406", + "log(address,uint256,string,uint256)": "bf01f891", + "log(address,uint256,uint256)": "b69bcaf6", + "log(address,uint256,uint256,address)": "20e3984d", + "log(address,uint256,uint256,bool)": "66f1bc67", + "log(address,uint256,uint256,string)": "4a28c017", + "log(address,uint256,uint256,uint256)": "34f0e636", + "log(bool)": "32458eed", + "log(bool,address)": "853c4849", + "log(bool,address,address)": "d2763667", + "log(bool,address,address,address)": "1d14d001", + "log(bool,address,address,bool)": "46600be0", + "log(bool,address,address,string)": "d812a167", + "log(bool,address,address,uint256)": "0c66d1be", + "log(bool,address,bool)": "18c9c746", + "log(bool,address,bool,address)": "1c41a336", + "log(bool,address,bool,bool)": "6a9c478b", + "log(bool,address,bool,string)": "4a66cb34", + "log(bool,address,bool,uint256)": "07831502", + "log(bool,address,string)": "de9a9270", + "log(bool,address,string,address)": "6f7c603e", + "log(bool,address,string,bool)": "e2bfd60b", + "log(bool,address,string,string)": "a73c1db6", + "log(bool,address,string,uint256)": "c21f64c7", + "log(bool,address,uint256)": "5f7b9afb", + "log(bool,address,uint256,address)": "136b05dd", + "log(bool,address,uint256,bool)": "d6019f1c", + "log(bool,address,uint256,string)": "51f09ff8", + "log(bool,address,uint256,uint256)": "7bf181a1", + "log(bool,bool)": "2a110e83", + "log(bool,bool,address)": "1078f68d", + "log(bool,bool,address,address)": "f4880ea4", + "log(bool,bool,address,bool)": "c0a302d8", + "log(bool,bool,address,string)": "a0a47963", + "log(bool,bool,address,uint256)": "4c123d57", + "log(bool,bool,bool)": "50709698", + "log(bool,bool,bool,address)": "8c329b1a", + "log(bool,bool,bool,bool)": "3b2a5ce0", + "log(bool,bool,bool,string)": "2ae408d4", + "log(bool,bool,bool,uint256)": "6d7045c1", + "log(bool,bool,string)": "2555fa46", + "log(bool,bool,string,address)": "f9ad2b89", + "log(bool,bool,string,bool)": "b857163a", + "log(bool,bool,string,string)": "6d1e8751", + "log(bool,bool,string,uint256)": "e3a9ca2f", + "log(bool,bool,uint256)": "12f21602", + "log(bool,bool,uint256,address)": "54a7a9a0", + "log(bool,bool,uint256,bool)": "619e4d0e", + "log(bool,bool,uint256,string)": "7dd4d0e0", + "log(bool,bool,uint256,uint256)": "0bb00eab", + "log(bool,string)": "8feac525", + "log(bool,string,address)": "9591b953", + "log(bool,string,address,address)": "2b2b18dc", + "log(bool,string,address,bool)": "6dd434ca", + "log(bool,string,address,string)": "12d6c788", + "log(bool,string,address,uint256)": "a5cada94", + "log(bool,string,bool)": "dbb4c247", + "log(bool,string,bool,address)": "538e06ab", + "log(bool,string,bool,bool)": "dc5e935b", + "log(bool,string,bool,string)": "483d0416", + "log(bool,string,bool,uint256)": "1606a393", + "log(bool,string,string)": "b076847f", + "log(bool,string,string,address)": "97d394d8", + "log(bool,string,string,bool)": "1e4b87e5", + "log(bool,string,string,string)": "1762e32a", + "log(bool,string,string,uint256)": "7be0c3eb", + "log(bool,string,uint256)": "1093ee11", + "log(bool,string,uint256,address)": "1596a1ce", + "log(bool,string,uint256,bool)": "6b0e5d53", + "log(bool,string,uint256,string)": "1ad96de6", + "log(bool,string,uint256,uint256)": "28863fcb", + "log(bool,uint256)": "399174d3", + "log(bool,uint256,address)": "088ef9d2", + "log(bool,uint256,address,address)": "26f560a8", + "log(bool,uint256,address,bool)": "b4c314ff", + "log(bool,uint256,address,string)": "1bb3b09a", + "log(bool,uint256,address,uint256)": "1537dc87", + "log(bool,uint256,bool)": "e8defba9", + "log(bool,uint256,bool,address)": "9acd3616", + "log(bool,uint256,bool,bool)": "ceb5f4d7", + "log(bool,uint256,bool,string)": "9143dbb1", + "log(bool,uint256,bool,uint256)": "7f9bbca2", + "log(bool,uint256,string)": "c3fc3970", + "log(bool,uint256,string,address)": "fedd1fff", + "log(bool,uint256,string,bool)": "e5e70b2b", + "log(bool,uint256,string,string)": "f5bc2249", + "log(bool,uint256,string,uint256)": "6a1199e2", + "log(bool,uint256,uint256)": "37103367", + "log(bool,uint256,uint256,address)": "00dd87b9", + "log(bool,uint256,uint256,bool)": "be984353", + "log(bool,uint256,uint256,string)": "8e69fb5d", + "log(bool,uint256,uint256,uint256)": "374bb4b2", + "log(int256)": "2d5b6cb9", + "log(string)": "41304fac", + "log(string,address)": "319af333", + "log(string,address,address)": "fcec75e0", + "log(string,address,address,address)": "ed8f28f6", + "log(string,address,address,bool)": "b59dbd60", + "log(string,address,address,string)": "800a1c67", + "log(string,address,address,uint256)": "8ef3f399", + "log(string,address,bool)": "c91d5ed4", + "log(string,address,bool,address)": "223603bd", + "log(string,address,bool,bool)": "79884c2b", + "log(string,address,bool,string)": "0454c079", + "log(string,address,bool,uint256)": "3e9f866a", + "log(string,address,string)": "e0e9ad4f", + "log(string,address,string,address)": "aabc9a31", + "log(string,address,string,bool)": "5f15d28c", + "log(string,address,string,string)": "245986f2", + "log(string,address,string,uint256)": "91d1112e", + "log(string,address,uint256)": "0d26b925", + "log(string,address,uint256,address)": "63fb8bc5", + "log(string,address,uint256,bool)": "fc4845f0", + "log(string,address,uint256,string)": "5a477632", + "log(string,address,uint256,uint256)": "f8f51b1e", + "log(string,bool)": "c3b55635", + "log(string,bool,address)": "932bbb38", + "log(string,bool,address,address)": "33e9dd1d", + "log(string,bool,address,bool)": "958c28c6", + "log(string,bool,address,string)": "2d8e33a4", + "log(string,bool,address,uint256)": "5d08bb05", + "log(string,bool,bool)": "850b7ad6", + "log(string,bool,bool,address)": "7190a529", + "log(string,bool,bool,bool)": "895af8c5", + "log(string,bool,bool,string)": "9d22d5dd", + "log(string,bool,bool,uint256)": "8e3f78a9", + "log(string,bool,string)": "e298f47d", + "log(string,bool,string,address)": "e0625b29", + "log(string,bool,string,bool)": "3f8a701d", + "log(string,bool,string,string)": "a826caeb", + "log(string,bool,string,uint256)": "24f91465", + "log(string,bool,uint256)": "c95958d6", + "log(string,bool,uint256,address)": "935e09bf", + "log(string,bool,uint256,bool)": "8af7cf8a", + "log(string,bool,uint256,string)": "742d6ee7", + "log(string,bool,uint256,uint256)": "64b5bb67", + "log(string,int256)": "3ca6268e", + "log(string,string)": "4b5c4277", + "log(string,string,address)": "95ed0195", + "log(string,string,address,address)": "439c7bef", + "log(string,string,address,bool)": "5ccd4e37", + "log(string,string,address,string)": "eb1bff80", + "log(string,string,address,uint256)": "7cc3c607", + "log(string,string,bool)": "b0e0f9b5", + "log(string,string,bool,address)": "c371c7db", + "log(string,string,bool,bool)": "40785869", + "log(string,string,bool,string)": "5e84b0ea", + "log(string,string,bool,uint256)": "d6aefad2", + "log(string,string,string)": "2ced7cef", + "log(string,string,string,address)": "6d572f44", + "log(string,string,string,bool)": "2c1754ed", + "log(string,string,string,string)": "de68f20a", + "log(string,string,string,uint256)": "8eafb02b", + "log(string,string,uint256)": "5821efa1", + "log(string,string,uint256,address)": "1023f7b2", + "log(string,string,uint256,bool)": "c3a8a654", + "log(string,string,uint256,string)": "5d1a971a", + "log(string,string,uint256,uint256)": "f45d7d2c", + "log(string,uint256)": "b60e72cc", + "log(string,uint256,address)": "1c7ec448", + "log(string,uint256,address,address)": "5ea2b7ae", + "log(string,uint256,address,bool)": "82112a42", + "log(string,uint256,address,string)": "9ffb2f93", + "log(string,uint256,address,uint256)": "4f04fdc6", + "log(string,uint256,bool)": "ca7733b1", + "log(string,uint256,bool,address)": "e0e95b98", + "log(string,uint256,bool,bool)": "354c36d6", + "log(string,uint256,bool,string)": "abf73a98", + "log(string,uint256,bool,uint256)": "e41b6f6f", + "log(string,uint256,string)": "5970e089", + "log(string,uint256,string,address)": "7c4632a4", + "log(string,uint256,string,bool)": "7d24491d", + "log(string,uint256,string,string)": "5ab84e1f", + "log(string,uint256,string,uint256)": "c67ea9d1", + "log(string,uint256,uint256)": "ca47c4eb", + "log(string,uint256,uint256,address)": "e21de278", + "log(string,uint256,uint256,bool)": "7626db92", + "log(string,uint256,uint256,string)": "854b3496", + "log(string,uint256,uint256,uint256)": "a7a87853", + "log(uint256)": "f82c50f1", + "log(uint256,address)": "69276c86", + "log(uint256,address,address)": "bcfd9be0", + "log(uint256,address,address,address)": "2488b414", + "log(uint256,address,address,bool)": "091ffaf5", + "log(uint256,address,address,string)": "031c6f73", + "log(uint256,address,address,uint256)": "736efbb6", + "log(uint256,address,bool)": "9b6ec042", + "log(uint256,address,bool,address)": "ef72c513", + "log(uint256,address,bool,bool)": "e351140f", + "log(uint256,address,bool,string)": "90fb06aa", + "log(uint256,address,bool,uint256)": "5abd992a", + "log(uint256,address,string)": "63cb41f9", + "log(uint256,address,string,address)": "9cba8fff", + "log(uint256,address,string,bool)": "cc32ab07", + "log(uint256,address,string,string)": "3e128ca3", + "log(uint256,address,string,uint256)": "46826b5d", + "log(uint256,address,uint256)": "5a9b5ed5", + "log(uint256,address,uint256,address)": "15c127b5", + "log(uint256,address,uint256,bool)": "5f743a7c", + "log(uint256,address,uint256,string)": "ddb06521", + "log(uint256,address,uint256,uint256)": "0c9cd9c1", + "log(uint256,bool)": "1c9d7eb3", + "log(uint256,bool,address)": "35085f7b", + "log(uint256,bool,address,address)": "a1ef4cbb", + "log(uint256,bool,address,bool)": "454d54a5", + "log(uint256,bool,address,string)": "ade052c7", + "log(uint256,bool,address,uint256)": "078287f5", + "log(uint256,bool,bool)": "20718650", + "log(uint256,bool,bool,address)": "69640b59", + "log(uint256,bool,bool,bool)": "b6f577a1", + "log(uint256,bool,bool,string)": "dddb9561", + "log(uint256,bool,bool,uint256)": "7464ce23", + "log(uint256,bool,string)": "85775021", + "log(uint256,bool,string,address)": "ef529018", + "log(uint256,bool,string,bool)": "eb928d7f", + "log(uint256,bool,string,string)": "68c8b8bd", + "log(uint256,bool,string,uint256)": "2c1d0746", + "log(uint256,bool,uint256)": "20098014", + "log(uint256,bool,uint256,address)": "88cb6041", + "log(uint256,bool,uint256,bool)": "91a02e2a", + "log(uint256,bool,uint256,string)": "de03e774", + "log(uint256,bool,uint256,uint256)": "c6acc7a8", + "log(uint256,string)": "643fd0df", + "log(uint256,string,address)": "7afac959", + "log(uint256,string,address,address)": "6168ed61", + "log(uint256,string,address,bool)": "90c30a56", + "log(uint256,string,address,string)": "9c3adfa1", + "log(uint256,string,address,uint256)": "e8d3018d", + "log(uint256,string,bool)": "4ceda75a", + "log(uint256,string,bool,address)": "ae2ec581", + "log(uint256,string,bool,bool)": "ba535d9c", + "log(uint256,string,bool,string)": "d2d423cd", + "log(uint256,string,bool,uint256)": "cf009880", + "log(uint256,string,string)": "b115611f", + "log(uint256,string,string,address)": "d583c602", + "log(uint256,string,string,bool)": "b3a6b6bd", + "log(uint256,string,string,string)": "21ad0683", + "log(uint256,string,string,uint256)": "b028c9bd", + "log(uint256,string,uint256)": "37aa7d4c", + "log(uint256,string,uint256,address)": "3b2279b4", + "log(uint256,string,uint256,bool)": "691a8f74", + "log(uint256,string,uint256,string)": "b7b914ca", + "log(uint256,string,uint256,uint256)": "82c25b74", + "log(uint256,uint256)": "f666715a", + "log(uint256,uint256,address)": "5c96b331", + "log(uint256,uint256,address,address)": "56a5d1b1", + "log(uint256,uint256,address,bool)": "15cac476", + "log(uint256,uint256,address,string)": "6cde40b8", + "log(uint256,uint256,address,uint256)": "88f6e4b2", + "log(uint256,uint256,bool)": "4766da72", + "log(uint256,uint256,bool,address)": "9a816a83", + "log(uint256,uint256,bool,bool)": "ab085ae6", + "log(uint256,uint256,bool,string)": "a5b4fc99", + "log(uint256,uint256,bool,uint256)": "eb7f6fd2", + "log(uint256,uint256,string)": "71d04af2", + "log(uint256,uint256,string,address)": "42d21db7", + "log(uint256,uint256,string,bool)": "7af6ab25", + "log(uint256,uint256,string,string)": "27d8afd2", + "log(uint256,uint256,string,uint256)": "5da297eb", + "log(uint256,uint256,uint256)": "d1ed7a3c", + "log(uint256,uint256,uint256,address)": "fa8185af", + "log(uint256,uint256,uint256,bool)": "c598d185", + "log(uint256,uint256,uint256,string)": "59cfcbe3", + "log(uint256,uint256,uint256,uint256)": "193fb800", + "logAddress(address)": "5f91b0af", + "logBool(bool)": "ba7ab84e", + "logBytes(bytes)": "e17bf956", + "logBytes1(bytes1)": "6f4171c9", + "logBytes10(bytes10)": "9dc2a897", + "logBytes11(bytes11)": "dc08b6a7", + "logBytes12(bytes12)": "7656d6c7", + "logBytes13(bytes13)": "34c1d81b", + "logBytes14(bytes14)": "3ceaba65", + "logBytes15(bytes15)": "591a3da2", + "logBytes16(bytes16)": "1f8d7312", + "logBytes17(bytes17)": "f89a532f", + "logBytes18(bytes18)": "d8652642", + "logBytes19(bytes19)": "00f56bc9", + "logBytes2(bytes2)": "9b5e943e", + "logBytes20(bytes20)": "ecb8567e", + "logBytes21(bytes21)": "3052c08f", + "logBytes22(bytes22)": "807ab434", + "logBytes23(bytes23)": "4979b037", + "logBytes24(bytes24)": "0977aefc", + "logBytes25(bytes25)": "aea9963f", + "logBytes26(bytes26)": "d3635628", + "logBytes27(bytes27)": "fc372f9f", + "logBytes28(bytes28)": "382f9a34", + "logBytes29(bytes29)": "7a187641", + "logBytes3(bytes3)": "7782fa2d", + "logBytes30(bytes30)": "c4340ef6", + "logBytes31(bytes31)": "81fc8648", + "logBytes32(bytes32)": "2d21d6f7", + "logBytes4(bytes4)": "fba3ad39", + "logBytes5(bytes5)": "5583be2e", + "logBytes6(bytes6)": "4942adc6", + "logBytes7(bytes7)": "4574afab", + "logBytes8(bytes8)": "9902e47f", + "logBytes9(bytes9)": "50a138df", + "logInt(int256)": "6525b5f5", + "logString(string)": "0bb563d6", + "logUint(uint256)": "9905b744" +} \ No newline at end of file diff --git a/suave/consolelog/consolelog.go b/suave/consolelog/consolelog.go new file mode 100644 index 000000000..1daeb4c33 --- /dev/null +++ b/suave/consolelog/consolelog.go @@ -0,0 +1,91 @@ +package consolelog + +import ( + _ "embed" + "encoding/hex" + "encoding/json" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +// embed the consolelog2 artifact with the method indentifiers +// +//go:embed console2.json +var console2Artifact string + +// console2Methods is a map of method signatures to their +// types. It is populated by loadConsole2Methods +var console2Methods map[string]abi.Type + +// Console2ContractAddr is the address of the console2 contract +var Console2ContractAddr = common.HexToAddress("0x000000000000000000636F6e736F6c652e6c6f67") + +func decode(b []byte) (interface{}, error) { + if len(b) < 4 { + return nil, fmt.Errorf("invalid console log: %v", b) + } + + var sig []byte + sig, b = b[:4], b[4:] + + typ, ok := console2Methods[hex.EncodeToString(sig)] + if !ok { + return nil, fmt.Errorf("unknown console log method: %v", sig) + } + + val, err := typ.Unpack(b) + if err != nil { + return nil, err + } + + return val, nil +} + +// Print prints the given bytes to the console +func Print(b []byte) error { + val, err := decode(b) + if err != nil { + return err + } + + fmt.Printf("%v\n", val) + return nil +} + +func loadConsole2Methods() { + console2Methods = make(map[string]abi.Type) + + var console2MethodIdentifiers map[string]string + if err := json.Unmarshal([]byte(console2Artifact), &console2MethodIdentifiers); err != nil { + panic(err) + } + + for sig, sigID := range console2MethodIdentifiers { + // convert the signature of the method into the form + // tuple(...) + indx := strings.Index(sig, "(") + if indx == -1 { + panic(fmt.Errorf("invalid signature for %s", sig)) + } + + typ, err := abi.NewTypeFromString("tuple" + sig[indx:]) + if err != nil { + panic(fmt.Errorf("invalid signature for %s: %v", "tuple"+sig[indx:], err)) + } + + // validate that the string representation of the type + // matches the signature + if !strings.HasSuffix(sig, typ.String()) { + panic(fmt.Errorf("invalid signature for %s: %s", sig, typ.String())) + } + + console2Methods[sigID] = typ + } +} + +func init() { + loadConsole2Methods() +} diff --git a/suave/consolelog/consolelog_test.go b/suave/consolelog/consolelog_test.go new file mode 100644 index 000000000..a01cac2bc --- /dev/null +++ b/suave/consolelog/consolelog_test.go @@ -0,0 +1,40 @@ +package consolelog + +import ( + "strings" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" +) + +func TestConsoleLog(t *testing.T) { + data := emitConsoleLog("log(address)", common.Address{}) + val, err := decode(data) + require.NoError(t, err) + require.NotNil(t, val) +} + +func emitConsoleLog(typStr string, args interface{}) []byte { + // decode the type and encode the arguments + typ, err := abi.NewTypeFromString(typStr[strings.Index(typStr, "("):]) + if err != nil { + panic(err) + } + + // pack the arguments + data, err := typ.Pack(args) + if err != nil { + panic(err) + } + + sig := crypto.Keccak256Hash([]byte(typStr)) + + buf := make([]byte, 0) + buf = append(buf, sig[:4]...) + buf = append(buf, data...) + + return buf +} diff --git a/suave/e2e/workflow_test.go b/suave/e2e/workflow_test.go index 28d1842f7..ef982f520 100644 --- a/suave/e2e/workflow_test.go +++ b/suave/e2e/workflow_test.go @@ -1158,6 +1158,19 @@ func TestE2EOnChainStateTransition(t *testing.T) { require.Error(t, err) } +func TestE2EConsoleLog(t *testing.T) { + fr := newFramework(t) + defer fr.Close() + + clt := fr.NewSDKClient() + + contractAddr := common.Address{0x3} + sourceContract := sdk.GetContract(contractAddr, exampleCallSourceContract.Abi, clt) + + _, err := sourceContract.SendTransaction("consoleLog", []interface{}{}, nil) + require.NoError(t, err) +} + func TestE2ERemoteCalls(t *testing.T) { fr := newFramework(t, WithWhitelist([]string{"127.0.0.1"})) defer fr.Close() diff --git a/suave/sol/standard_peekers/example.sol b/suave/sol/standard_peekers/example.sol index 0e03fff71..2a105bf7b 100644 --- a/suave/sol/standard_peekers/example.sol +++ b/suave/sol/standard_peekers/example.sol @@ -1,6 +1,7 @@ pragma solidity ^0.8.8; import "../libraries/Suave.sol"; +import "forge-std/console2.sol"; contract ExampleEthCallSource { uint64 state; @@ -15,6 +16,10 @@ contract ExampleEthCallSource { state++; } + function consoleLog() public payable { + console2.log(1, 2, 3); + } + function remoteCall(Suave.HttpRequest memory request) public { Suave.doHTTPRequest(request); }