diff --git a/.tool-versions b/.tool-versions index 25e3e8a1..a50ce8eb 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,5 +1,5 @@ circleci 0.1.31425 -golang 1.23.6 +golang 1.24.5 golangci-lint 1.64.5 nodejs 18.17.0 postgres 14.2 diff --git a/rolling-shutter/go.mod b/rolling-shutter/go.mod index ead1c91b..da3c827b 100644 --- a/rolling-shutter/go.mod +++ b/rolling-shutter/go.mod @@ -32,7 +32,6 @@ require ( github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.22.0 github.com/rs/zerolog v1.28.0 - github.com/shutter-network/contracts/v2 v2.0.0-beta.2.0.20250108084129-3b743179373a github.com/shutter-network/gnosh-contracts v0.4.0 github.com/shutter-network/shop-contracts v0.0.0-20240407151512-08ef5d8355b6 github.com/shutter-network/shutter/shlib v0.1.19 @@ -61,6 +60,7 @@ require ( require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/VictoriaMetrics/fastcache v1.12.2 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.17.0 // indirect @@ -68,12 +68,19 @@ require ( github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v1.1.2 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.22 // indirect github.com/consensys/gnark-crypto v0.14.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cosmos/gogoproto v1.4.1 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect github.com/crate-crypto/go-kzg-4844 v1.1.0 // indirect github.com/creachadair/taskgroup v0.3.2 // indirect @@ -92,6 +99,7 @@ require ( github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect @@ -103,7 +111,9 @@ require ( github.com/go-openapi/swag v0.22.4 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.0.1 // indirect @@ -119,6 +129,8 @@ require ( github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect + github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.3.2 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -165,6 +177,7 @@ require ( github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect + github.com/mitchellh/pointerstructure v1.2.1 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect @@ -177,6 +190,7 @@ require ( github.com/multiformats/go-multistream v0.6.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo/v2 v2.22.2 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -196,6 +210,7 @@ require ( github.com/pion/sdp/v3 v3.0.10 // indirect github.com/pion/srtp/v3 v3.0.4 // indirect github.com/pion/stun v0.6.1 // indirect + github.com/pion/stun/v2 v2.0.0 // indirect github.com/pion/stun/v3 v3.0.0 // indirect github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/transport/v3 v3.0.7 // indirect @@ -214,6 +229,7 @@ require ( github.com/rivo/uniseg v0.4.3 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/rs/cors v1.9.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -224,8 +240,10 @@ require ( github.com/tendermint/tm-db v0.6.7 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect + github.com/urfave/cli/v2 v2.27.5 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/wlynxg/anet v0.0.5 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect @@ -240,11 +258,13 @@ require ( golang.org/x/net v0.40.0 // indirect golang.org/x/sys v0.33.0 // indirect golang.org/x/text v0.25.0 // indirect + golang.org/x/time v0.9.0 // indirect golang.org/x/tools v0.33.0 // indirect gonum.org/v1/gonum v0.16.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect google.golang.org/grpc v1.67.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect lukechampine.com/blake3 v1.4.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect diff --git a/rolling-shutter/go.sum b/rolling-shutter/go.sum index 4fe2175c..80139170 100644 --- a/rolling-shutter/go.sum +++ b/rolling-shutter/go.sum @@ -67,6 +67,8 @@ github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrd github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= @@ -96,6 +98,7 @@ github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -108,6 +111,8 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= @@ -145,7 +150,6 @@ github.com/cosmos/gogoproto v1.4.1 h1:WoyH+0/jbCTzpKNvyav5FL1ZTWsp1im1MxEpJEzKUB github.com/cosmos/gogoproto v1.4.1/go.mod h1:Ac9lzL4vFpBMcptJROQ6dQ4M3pOEK5Z/l0Q9p+LoCr4= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -244,6 +248,8 @@ github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJ github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -296,7 +302,6 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -630,6 +635,7 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -743,6 +749,8 @@ github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssy github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b h1:vab8deKC4QoIfm9fJM59iuNz1ELGsuLoYYpiF+pHiG8= github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pion/datachannel v1.5.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk4o= github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oLo8Rs4Py/M= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= @@ -781,6 +789,7 @@ github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1A github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM= @@ -836,7 +845,6 @@ github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OK github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -873,8 +881,6 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/shutter-network/contracts/v2 v2.0.0-beta.2.0.20250108084129-3b743179373a h1:hWw2nJLGPZU7Rvd6YmEEDfvlTUbwZKZl5UP2ThVVNSU= -github.com/shutter-network/contracts/v2 v2.0.0-beta.2.0.20250108084129-3b743179373a/go.mod h1:V8KhVM75wyWVSzZJ6GeC9dWCjRrinIQVb7mYNP+knbg= github.com/shutter-network/gnosh-contracts v0.4.0 h1:2GJcHK9w4lJZMsccklmxDhNnrkRLJDRwsL1acBnAeak= github.com/shutter-network/gnosh-contracts v0.4.0/go.mod h1:QB0d64ybbVFKMrLjrc1tldri87KNjTmKQjhk9jaso2E= github.com/shutter-network/shop-contracts v0.0.0-20240407151512-08ef5d8355b6 h1:m6Ti1/IH+GBTtGqyAX3xbh+ruUKvC+m+/uzYDUa+JDQ= @@ -962,7 +968,6 @@ github.com/ulope/jrpc2 v0.0.0-20230706135348-a95cf3d96bd2/go.mod h1:bzOCUO4YLqjP github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh33pStIp/E30b7TxDlXfM0145bn2e8boI30IxAhTg= github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= @@ -1256,6 +1261,7 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= diff --git a/rolling-shutter/keyperimpl/shutterservice/database/models.sqlc.gen.go b/rolling-shutter/keyperimpl/shutterservice/database/models.sqlc.gen.go index e62bcae0..77e1e2c6 100644 --- a/rolling-shutter/keyperimpl/shutterservice/database/models.sqlc.gen.go +++ b/rolling-shutter/keyperimpl/shutterservice/database/models.sqlc.gen.go @@ -17,6 +17,20 @@ type DecryptionSignature struct { Signature []byte } +type EventTriggerRegisteredEvent struct { + BlockNumber int64 + BlockHash []byte + TxIndex int64 + LogIndex int64 + Eon int64 + IdentityPrefix []byte + Sender string + Definition []byte + Decrypted bool + Identity []byte + Ttl int64 +} + type IdentityRegisteredEvent struct { BlockNumber int64 BlockHash []byte diff --git a/rolling-shutter/keyperimpl/shutterservice/database/shutterservice.sqlc.gen.go b/rolling-shutter/keyperimpl/shutterservice/database/shutterservice.sqlc.gen.go index b860afe6..7ec15fef 100644 --- a/rolling-shutter/keyperimpl/shutterservice/database/shutterservice.sqlc.gen.go +++ b/rolling-shutter/keyperimpl/shutterservice/database/shutterservice.sqlc.gen.go @@ -146,6 +146,59 @@ func (q *Queries) InsertDecryptionSignature(ctx context.Context, arg InsertDecry return err } +const insertEventTriggerRegisteredEvent = `-- name: InsertEventTriggerRegisteredEvent :execresult +INSERT INTO event_trigger_registered_event ( + block_number, + block_hash, + tx_index, + log_index, + eon, + identity_prefix, + sender, + definition, + ttl, + identity +) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) +ON CONFLICT (identity_prefix, sender) DO UPDATE SET +block_number = $1, +block_hash = $2, +tx_index = $3, +log_index = $4, +sender = $7, +definition = $8, +ttl = $9, +identity = $10 +` + +type InsertEventTriggerRegisteredEventParams struct { + BlockNumber int64 + BlockHash []byte + TxIndex int64 + LogIndex int64 + Eon int64 + IdentityPrefix []byte + Sender string + Definition []byte + Ttl int64 + Identity []byte +} + +func (q *Queries) InsertEventTriggerRegisteredEvent(ctx context.Context, arg InsertEventTriggerRegisteredEventParams) (pgconn.CommandTag, error) { + return q.db.Exec(ctx, insertEventTriggerRegisteredEvent, + arg.BlockNumber, + arg.BlockHash, + arg.TxIndex, + arg.LogIndex, + arg.Eon, + arg.IdentityPrefix, + arg.Sender, + arg.Definition, + arg.Ttl, + arg.Identity, + ) +} + const insertIdentityRegisteredEvent = `-- name: InsertIdentityRegisteredEvent :execresult INSERT INTO identity_registered_event ( block_number, @@ -246,3 +299,21 @@ func (q *Queries) UpdateDecryptedFlag(ctx context.Context, arg UpdateDecryptedFl _, err := q.db.Exec(ctx, updateDecryptedFlag, arg.Column1, arg.Column2) return err } + +const updateEventTriggerDecryptedFlag = `-- name: UpdateEventTriggerDecryptedFlag :exec +UPDATE event_trigger_registered_event +SET decrypted = TRUE +WHERE (eon, identity) IN ( + SELECT UNNEST($1::bigint[]), UNNEST($2::bytea[]) +) +` + +type UpdateEventTriggerDecryptedFlagParams struct { + Column1 []int64 + Column2 [][]byte +} + +func (q *Queries) UpdateEventTriggerDecryptedFlag(ctx context.Context, arg UpdateEventTriggerDecryptedFlagParams) error { + _, err := q.db.Exec(ctx, updateEventTriggerDecryptedFlag, arg.Column1, arg.Column2) + return err +} diff --git a/rolling-shutter/keyperimpl/shutterservice/database/sql/queries/shutterservice.sql b/rolling-shutter/keyperimpl/shutterservice/database/sql/queries/shutterservice.sql index 4218b4de..c48811c5 100644 --- a/rolling-shutter/keyperimpl/shutterservice/database/sql/queries/shutterservice.sql +++ b/rolling-shutter/keyperimpl/shutterservice/database/sql/queries/shutterservice.sql @@ -27,6 +27,38 @@ WHERE eon = $1 AND identities_hash = $2 ORDER BY keyper_index ASC LIMIT $3; +-- name: UpdateEventTriggerDecryptedFlag :exec +UPDATE event_trigger_registered_event +SET decrypted = TRUE +WHERE (eon, identity) IN ( + SELECT UNNEST($1::bigint[]), UNNEST($2::bytea[]) +); + +-- name: InsertEventTriggerRegisteredEvent :execresult +INSERT INTO event_trigger_registered_event ( + block_number, + block_hash, + tx_index, + log_index, + eon, + identity_prefix, + sender, + definition, + ttl, + identity +) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) +ON CONFLICT (identity_prefix, sender) DO UPDATE SET +block_number = $1, +block_hash = $2, +tx_index = $3, +log_index = $4, +sender = $7, +definition = $8, +ttl = $9, +identity = $10; + + -- name: UpdateDecryptedFlag :exec UPDATE identity_registered_event SET decrypted = TRUE diff --git a/rolling-shutter/keyperimpl/shutterservice/database/sql/schemas/shutterservice.sql b/rolling-shutter/keyperimpl/shutterservice/database/sql/schemas/shutterservice.sql index 8ab32d3c..ee20ee6e 100644 --- a/rolling-shutter/keyperimpl/shutterservice/database/sql/schemas/shutterservice.sql +++ b/rolling-shutter/keyperimpl/shutterservice/database/sql/schemas/shutterservice.sql @@ -1,7 +1,22 @@ --- schema-version: shutterservice-1 -- +-- schema-version: shutterservice-2 -- -- Please change the version above if you make incompatible changes to -- the schema. We'll use this to check we're using the right schema. +CREATE TABLE event_trigger_registered_event ( + block_number bigint NOT NULL CHECK (block_number >= 0), + block_hash bytea NOT NULL, + tx_index bigint NOT NULL CHECK (tx_index >= 0), + log_index bigint NOT NULL CHECK (log_index >= 0), + eon bigint NOT NULL CHECK (eon >= 0), + identity_prefix bytea NOT NULL, + sender text NOT NULL, + definition bytea NOT NULL, + decrypted boolean NOT NULL DEFAULT false, + identity bytea NOT NULL, + ttl bigint NOT NULL CHECK (ttl >= 0), + PRIMARY KEY (identity_prefix, sender) +); + CREATE TABLE identity_registered_event ( block_number bigint NOT NULL CHECK (block_number >= 0), block_hash bytea NOT NULL, diff --git a/rolling-shutter/keyperimpl/shutterservice/eventtrigger.go b/rolling-shutter/keyperimpl/shutterservice/eventtrigger.go new file mode 100644 index 00000000..71f29414 --- /dev/null +++ b/rolling-shutter/keyperimpl/shutterservice/eventtrigger.go @@ -0,0 +1,599 @@ +package shutterservice + +import ( + "bytes" + "fmt" + "io" + "math/big" + "strings" + "text/scanner" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" +) + +// ABI encoding word size +const ( + WORD = 32 + VERSION = 0x1 +) + +// # Trigger definition +// ## Comparison operators +// "eq", "lt", "lte", "gt", "gte" for number types, "match" for bytes32 and "cmatch" for complex []bytes +// +// ## ABI-Event: +// +// { +// "contract": "0xdead..beef", +// "signature": "Transfer(address from indexed, address to indexed, uint256 amount)", +// "conditions": [ +// {"to": {"match": "0xdead...beef"}}, +// {"amount": {"gte": 1}} +// ], +// } +// +// Note: fields that are not referenced in "conditions" are not restricted. +// +// ## RAW-Event: +// A user may not have the event-ABI available, or may not want to share it. +// +// { +// "contract": "0xdead..beef", +// "rawsig": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", +// "rawconditions": [ +// {"topic1": "any"}, +// {"topic2": {"match": "0xdead..beef"}}, +// {"data": { +// "arg": 0, +// "cast": "uint256", +// "gte": 1 +// } +// }, +// ], +// } +// +// Note: in order to allow for successful matching/parsing, _all_ "topics" must be referenced -- "any" allows for no restrictions. +// +// ## Condensed encoding (v1) +// We need this condensed encoding for registering trigger conditions on the blockchain (most likely as an event......) +// +// [0] version byte == 1 +// [1:33] address +// [33:65] topic0/raw signature +// [65] topic pattern (3 bit mask for topic1, topic2, topic3) +// [66:matching_topics_number*32] matching hashes for topics +// [*:end] DATA matches (see Condition.Bytes()) + +type EventTriggerDefinition struct { + Contract common.Address + Signature EvtSignature + Conditions []Condition +} + +func (e *EventTriggerDefinition) MarshalBytes() [][]byte { + // write version string to buffer 'work' + // write common fields to buffer 'work' + // loop through conditions + // for TopicData append to 'work' + // for regular conditions append to buffer 'data' + // append 'data' to 'work' + + // slice 'work' into [][WORD]array + var buf []byte + work := bytes.NewBuffer(buf) + work.WriteByte(VERSION) + work.Write(e.Contract[:]) + written, err := work.Write(e.Signature.Topic0().Bytes()) + if written < 20 { + panic("no sig written") + } + if err != nil { + panic(err) + } + work.WriteByte(e.TopicPattern()) + var d []byte + data := bytes.NewBuffer(d) + for _, cond := range e.Conditions { + switch cond.Location.(type) { + case TopicData: + written, err := work.Write(cond.Constraint.(MatchConstraint).target) + if written != len(cond.Constraint.(MatchConstraint).target) { + panic("foo") + } + if err != nil { + panic("bar") + } + case OffsetData: + data.Write(cond.Bytes()) + } + } + work.Write(data.Bytes()) + contents := work.Bytes() + words := len(contents) / WORD + if len(contents)%WORD != 0 { + words++ + } + target := make([][]byte, words) + for i := range words { + target[i] = []byte(contents[i*WORD : (i+1)*WORD]) + } + return target +} + +func (e *EventTriggerDefinition) UnmarshalBytes(data [][]byte) error { + var cat []byte + for i := range data { + cat = append(cat, data[i]...) + } + + b := bytes.NewBuffer(cat) + version, err := readByte(b) + if err != nil { + return fmt.Errorf("failed to read version %w", err) + } + if version != VERSION { + return fmt.Errorf("version mismatch want: %v got %v", VERSION, version) + } + contract := b.Next(common.AddressLength) + signature := b.Next(common.HashLength) + e.Contract = common.BytesToAddress(contract) + signatureHash := common.Hash(signature) + e.Signature = EvtSignature{hashed: &signatureHash} + topicMask, err := readByte(b) + if err != nil { + return err + } + if 0b100&topicMask == 0b100 { + topic1, err := readHash(b) + if err != nil { + return err + } + e.Conditions = append(e.Conditions, Condition{ + Location: TopicData{number: 1}, + Constraint: MatchConstraint{target: topic1.Bytes()}, + }) + } + if 0b010&topicMask == 0b010 { + topic2, err := readHash(b) + if err != nil { + return err + } + e.Conditions = append(e.Conditions, Condition{ + Location: TopicData{number: 2}, + Constraint: MatchConstraint{target: topic2.Bytes()}, + }) + } + if 0b001&topicMask == 0b001 { + topic3, err := readHash(b) + if err != nil { + return err + } + e.Conditions = append(e.Conditions, Condition{ + Location: TopicData{number: 3}, + Constraint: MatchConstraint{target: topic3.Bytes()}, + }) + } + // we now have the minimum valid event trigger definition. + // from here on, getting 'io.EOF' can be legal. + for { + argnumber, err := readByte(b) + if err != nil { + break + } + matchtype, err := readByte(b) + if err != nil { + break + } + var constraint Constraint + switch MatchType(matchtype) { + case UNDEFINED: + break + case COMPLEX: + wc, err := readByte(b) + if err != nil { + break + } + wordcount := int(wc) + if wordcount == 0 { + break + } + arg, err := readWords(b, wordcount) + if err != nil { + return fmt.Errorf("trailing data when parsing complex %v", arg) + } + constraint = MatchConstraint{target: arg} + case MATCH: + arg, err := readWord(b) + if err != nil { + return fmt.Errorf("trailing data when parsing match %v", arg) + } + constraint = MatchConstraint{target: arg} + default: + // number constraint + arg, err := readWord(b) + if err != nil { + return fmt.Errorf("trailing data when parsing num constraint %v", arg) + } + argval := big.NewInt(0).SetBytes(arg) + constraint = NumConstraint{ + op: Op(matchtype), + target: argval, + } + } + condition := Condition{ + Location: OffsetData{ + argnumber: int(argnumber), + complex: matchtype == byte(COMPLEX), + }, + Constraint: constraint, + } + e.Conditions = append(e.Conditions, condition) + } + return nil +} + +func readByte(buf *bytes.Buffer) (byte, error) { + res := buf.Next(1) + if len(res) < 1 { + return 0, io.EOF + } + return res[0], nil +} + +func readWord(buf *bytes.Buffer) ([]byte, error) { + read := buf.Next(WORD) + if len(read) != WORD { + return read, fmt.Errorf("failed to read whole word") + } + return read[:], nil +} + +func readHash(buf *bytes.Buffer) (common.Hash, error) { + read := buf.Next(common.HashLength) + if len(read) != common.HashLength { + return common.BytesToHash(read), fmt.Errorf("failed to read whole word") + } + return common.BytesToHash(read[:]), nil +} + +func readWords(buf *bytes.Buffer, words int) ([]byte, error) { + var read []byte + for i := 0; i < words; i++ { + next, err := readWord(buf) + if err != nil { + return read, fmt.Errorf("error reading %v words %w", words, err) + } + read = append(read, next...) + } + return read[:], nil +} + +// Topic pattern: we need to specify, how many topics and in which position we reference +/* + +-+-+-+ + |1|2|3| + +-+-+-+ + |o|o|o| => 0 + +-+-+-+ + |o|o|x| => 1 + +-+-+-+ + |o|x|o| => 2 + +-+-+-+ + |o|x|x| => 3 + +-+-+-+ + |x|o|o| => 4 + +-+-+-+ + |x|o|x| => 5 + +-+-+-+ + |x|x|o| => 6 + +-+-+-+ + |x|x|x| => 7 + +-+-+-+ +*/ +func (e *EventTriggerDefinition) TopicPattern() byte { + v := make([]uint8, 3) + for _, cond := range e.Conditions { + switch cond.Location.(type) { + case TopicData: + v[cond.Location.(TopicData).number-1] = 1 + default: + continue + } + } + result := v[0] + (v[1] << 1) + (v[2] << 2) + return result +} + +func (e EventTriggerDefinition) ToFilterQuery() ethereum.FilterQuery { + // The Topic list restricts matches to particular event topics. Each event has a list + // of topics. Topics matches a prefix of that list. An empty element slice matches any + // topic. Non-empty elements represent an alternative that matches any of the + // contained topics. + // + // Examples: + // {} or nil matches any topic list + // {{A}} matches topic A in first position + // {{}, {B}} matches any topic in first position AND B in second position + // {{A}, {B}} matches topic A in first position AND B in second position + // {{A, B}, {C, D}} matches topic (A OR B) in first position AND (C OR D) in second position + // var Topics [][]common.Hash + topics := [][]common.Hash{ + {e.Signature.Topic0()}, + {}, + {}, + {}, + } + for _, cond := range e.Conditions { + switch cond.Location.(type) { + case TopicData: + d, ok := cond.Constraint.(MatchConstraint) + if !ok { + continue + } + topics[cond.Location.(TopicData).number] = []common.Hash{common.Hash(d.target)} + default: + continue + } + } + + query := ethereum.FilterQuery{ + BlockHash: nil, + FromBlock: nil, + ToBlock: nil, + Addresses: []common.Address{e.Contract}, + Topics: topics, + } + return query +} + +func (e *EventTriggerDefinition) Match(elog types.Log, testTopics bool) bool { + for _, c := range e.Conditions { + switch c.Location.(type) { + case TopicData: + continue + default: + if !c.Fullfilled(elog) { + return false + } + } + } + return true +} + +type EvtSignature struct { + long string + hashed *common.Hash +} + +func (e EvtSignature) toHashableSig() string { + var name string + var prev string + i := 0 + args := make([]string, 1+strings.Count(string(e.long), ",")) + var s scanner.Scanner + s.Init(strings.NewReader(string(e.long))) + for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { + if s.Position.Offset == 0 { + name = s.TokenText() + } else { + if prev == "(" || prev == "," { + args[i] = s.TokenText() + i++ + } + prev = s.TokenText() + } + } + result := fmt.Sprintf("%v(%v)", name, strings.Join(args, ",")) + return result +} + +func (e EvtSignature) Topic0() common.Hash { + if e.hashed != nil { + return *e.hashed + } + shortSig := e.toHashableSig() + + return common.Hash(crypto.Keccak256([]byte(shortSig))) +} + +type LogField interface { + GetSlice(l types.Log) []byte +} + +type TopicData struct { + number int +} + +func (t TopicData) String() string { + return fmt.Sprintf("topic%v", t.number) +} + +func (t TopicData) GetSlice(l types.Log) []byte { + return l.Topics[t.number].Bytes() +} + +type OffsetData struct { + argnumber int + complex bool +} + +func (o OffsetData) getSliceDef(l types.Log) (offset int64, size int64) { + start := o.argnumber * WORD + if o.complex { + slice := l.Data[start : start+WORD] + sizeword := big.NewInt(0).SetBytes(slice).Int64() + offset = sizeword + WORD + size = big.NewInt(0).SetBytes(l.Data[sizeword : sizeword+WORD]).Int64() + } else { + offset = int64(start) + size = WORD + } + return offset, size +} + +func (o OffsetData) GetSlice(l types.Log) []byte { + start, size := o.getSliceDef(l) + slice := l.Data[start : start+size] + return slice +} + +// TODO: TopicData can ONLY allow for MatchConstraint (due to values getting hashed into topics, so no numeric comparison possible) +type Condition struct { + Location LogField + Constraint Constraint +} + +func (c *Condition) Fullfilled(elog types.Log) bool { + val := c.Location.GetSlice(elog) + switch c.Constraint.(type) { + case NumConstraint: + num := c.Constraint.(NumConstraint) + return num.Test(num.GetValue(val)) + case MatchConstraint: + match := c.Constraint.(MatchConstraint) + return match.Test(match.GetValue(val)) + default: + return false + } +} + +type Op int + +const ( + LT Op = iota + 1 + LTE + EQ + GTE + GT +) + +var operatorSymbol = map[Op]string{ + LT: "<", + LTE: "<=", + EQ: "==", + GTE: "=>", + GT: ">", +} + +type MatchType byte + +const ( + UNDEFINED MatchType = iota + U256_LT + U256_LTE + U256_EQ + U256_GTE + U256_GT + MATCH + COMPLEX +) + +// Encoding for DATA matches: +// [0] argnumber (note: offset in data ==> argnumber * wordsize; for complex data types, this points to the offset marker in ABI encoding) +// [1] cast-matchtype-size {0: uint256-lt, 1: uint256-lte, 2: uint256-eq, 3: uint256-gte, 4:uint256-gt, 5: byte32-match, 6: []byte-complexmatch} +// [2:2+32] matchdata for 1 word matches OR +// [3] word count +// [3:3+X] matchdata for [X]byte-match (right padded for [WORD]byte) +func (c *Condition) Bytes() []byte { + var buf []byte + data := bytes.NewBuffer(buf) + switch c.Location.(type) { + case TopicData: + data.Write(c.Constraint.(MatchConstraint).target) + case OffsetData: + data.WriteByte(byte(c.Location.(OffsetData).argnumber)) + switch c.Constraint.(type) { + case NumConstraint: + data.WriteByte(byte(c.Constraint.(NumConstraint).op)) + data.Write(WordPad(c.Constraint.(NumConstraint).target.Bytes())) + case MatchConstraint: + matchBytes := c.Constraint.(MatchConstraint).target + if c.Location.(OffsetData).complex { + data.WriteByte(byte(COMPLEX)) + // align to WORD len and prepend with wordcount + words := len(matchBytes) / WORD + if len(matchBytes)%WORD != 0 { + words++ + } + data.WriteByte(byte(words)) + data.Write(matchBytes) + padBytes := make([]byte, len(matchBytes)%WORD) + data.Write(padBytes) + } else { + data.WriteByte(byte(MATCH)) + data.Write(matchBytes) + } + } + } + return data.Bytes()[:] +} + +type Constraint interface { + Test(t any) bool +} + +type NumConstraint struct { + op Op + target *big.Int +} + +func (n NumConstraint) Test(v any) bool { + value, ok := v.(*big.Int) + if !ok { + return false + } + switch n.op { + case LT: + return n.target.Cmp(value) > 0 + case LTE: + return n.target.Cmp(value) >= 0 + case EQ: + return n.target.Cmp(value) == 0 + case GTE: + return n.target.Cmp(value) <= 0 + case GT: + return n.target.Cmp(value) < 0 + default: + return false + } +} + +func (n NumConstraint) GetValue(slice []byte) *big.Int { + r := big.NewInt(0) + result := r.SetBytes(slice) + return result +} + +type MatchConstraint struct { + target []byte +} + +func (m MatchConstraint) GetValue(slice []byte) []byte { + return slice +} + +func (m MatchConstraint) Test(v any) bool { + value, ok := v.([]byte) + if !ok { + return false + } + if len(value) != len(m.target) { + return false + } + for i := range m.target { + if value[i] != m.target[i] { + return false + } + } + return true +} + +// This kind of padding is used for topics and other values that should be exactly 32byte/1 word +func WordPad(data []byte) []byte { + out := make([]byte, WORD) + copy(out[WORD-len(data):], data) + return out +} diff --git a/rolling-shutter/keyperimpl/shutterservice/eventtrigger_test.go b/rolling-shutter/keyperimpl/shutterservice/eventtrigger_test.go new file mode 100644 index 00000000..a6168c28 --- /dev/null +++ b/rolling-shutter/keyperimpl/shutterservice/eventtrigger_test.go @@ -0,0 +1,411 @@ +package shutterservice + +import ( + "context" + "crypto/ecdsa" + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient/simulated" + "github.com/ethereum/go-ethereum/params" + "gotest.tools/assert" + + "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/shutterservice/help" +) + +// This should match what is in help/erc20bindings.go +const ( + TestEvtSig = "Transfer(address,address,address,uint256,string)" + TestEvtSigFull = "Transfer(address from indexed, address to indexed, address notify indexed, uint256 amount, string foobar)" +) + +type TestSetup struct { + backend *simulated.Backend + erc20Address common.Address + erc20Contract *help.ERC20Basic + triggerRegistryAddress common.Address + triggerContract *help.ShutterRegistry + key *ecdsa.PrivateKey +} + +func SetupAndDeploy() (TestSetup, error) { + setup := TestSetup{} + + // Setup simulated block chain + key, _ := crypto.GenerateKey() + setup.key = key + auth, err := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + if err != nil { + return setup, err + } + alloc := make(types.GenesisAlloc) + alloc[auth.From] = types.Account{Balance: big.NewInt(10000000000000000)} + blockchain := simulated.NewBackend(alloc) + setup.backend = blockchain + + // Deploy erc20Contract + erc20Address, _, erc20Contract, err := help.DeployERC20Basic( + auth, + blockchain.Client(), + ) + if err != nil { + return setup, fmt.Errorf("failed to deploy ERC20 %w", err) + } + setup.erc20Address = erc20Address + setup.erc20Contract = erc20Contract + + // Deploy ShutterEventTrigger contract + triggerRegistryAddress, _, triggerContract, err := help.DeployShutterRegistry( + auth, + blockchain.Client(), + ) + if err != nil { + return setup, fmt.Errorf("failed to deploy TriggerRegistry %w", err) + } + setup.triggerRegistryAddress = triggerRegistryAddress + setup.triggerContract = triggerContract + // commit all pending transactions + blockchain.Commit() + return setup, nil +} + +// Test ERC20 contract gets deployed correctly +func TestEvtDeployContract(t *testing.T) { + setup, err := SetupAndDeploy() + assert.NilError(t, err, "setup and deploy failed") + + if len(setup.erc20Address.Bytes()) == 0 { + t.Error("Expected a valid deployment address. Received empty address byte array instead") + } +} + +func RegisterTrigger(t *testing.T, setup TestSetup, trigger EventTriggerDefinition) { + client := setup.backend.Client() + from := crypto.PubkeyToAddress(setup.key.PublicKey) + + head, _ := client.HeaderByNumber(context.Background(), nil) + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(params.GWei)) + chainid, _ := client.ChainID(context.Background()) + nonce, err := client.PendingNonceAt(context.Background(), from) + assert.NilError(t, err, "failed to get nonce") + signer := func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + return types.SignTx(tx, types.LatestSignerForChainID(chainid), setup.key) + } + + ttl := uint64(head.Number.Int64() + 10) + eon := uint64(1) + identityPrefix := crypto.Keccak256Hash([]byte("test")) + + assert.NilError(t, err, "failed to sign") + marshaledTrigger := trigger.MarshalBytes() + tx, err := setup.triggerContract.Register(&bind.TransactOpts{ + From: from, + Nonce: big.NewInt(int64(nonce)), + GasTipCap: big.NewInt(params.GWei), + GasFeeCap: gasPrice, + GasLimit: 2100000, + Signer: signer, + }, + eon, identityPrefix, marshaledTrigger, ttl) + assert.NilError(t, err, "error with token transfer") + txHash := tx.Hash() + assert.NilError(t, err, "error getting block") + setup.backend.Commit() + found, pending, err := client.TransactionByHash(context.Background(), txHash) + assert.NilError(t, err, "error getting tx") + assert.Check(t, pending == false, "still pending") + assert.Check(t, found.Hash() == txHash) + receipt, err := client.TransactionReceipt(context.Background(), txHash) + + assert.NilError(t, err, "error getting receipt") + assert.Check(t, receipt.Status == 1, "transfer failed") +} + +func ERC20Transfer(t *testing.T, setup TestSetup, from common.Address, to common.Address, amount int64) { + client := setup.backend.Client() + + head, _ := client.HeaderByNumber(context.Background(), nil) + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(params.GWei)) + chainid, _ := client.ChainID(context.Background()) + nonce, err := client.PendingNonceAt(context.Background(), from) + assert.NilError(t, err, "failed to get nonce") + signer := func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + return types.SignTx(tx, types.LatestSignerForChainID(chainid), setup.key) + } + + assert.NilError(t, err, "failed to sign") + tx, err := setup.erc20Contract.Transfer(&bind.TransactOpts{ + From: from, + Nonce: big.NewInt(int64(nonce)), + GasTipCap: big.NewInt(params.GWei), + GasFeeCap: gasPrice, + GasLimit: 2100000, + Signer: signer, + }, to, big.NewInt(amount)) + assert.NilError(t, err, "error with token transfer") + txHash := tx.Hash() + assert.NilError(t, err, "error getting block") + setup.backend.Commit() + found, pending, err := client.TransactionByHash(context.Background(), txHash) + assert.NilError(t, err, "error getting tx") + assert.Check(t, pending == false, "still pending") + assert.Check(t, found.Hash() == txHash) + receipt, err := client.TransactionReceipt(context.Background(), txHash) + + assert.NilError(t, err, "error getting receipt") + assert.Check(t, receipt.Status == 1, "transfer failed") +} + +func TestEvtBloomFilterMatch(t *testing.T) { + setup, err := SetupAndDeploy() + assert.NilError(t, err, "failure deploying") + addr := crypto.PubkeyToAddress(setup.key.PublicKey) + + ERC20Transfer(t, setup, addr, addr, 1) + latest, err := setup.backend.Client().BlockByNumber(context.Background(), nil) + assert.NilError(t, err, "error getting block") + + // topic0 signature + topic0 := crypto.Keccak256([]byte(TestEvtSig)) + assert.Check(t, latest.Bloom().Test(topic0), "could not find topic0") + + // topic1 address from indexed + topic1 := WordPad(addr.Bytes()) + assert.Check(t, latest.Bloom().Test(topic1), "could not find topic1") + + // topic2 address to indexed + topic2 := WordPad(addr.Bytes()) + assert.Check(t, latest.Bloom().Test(topic2), "could not find topic2") + + // we could probably calculate `bloom9.go:types.bloomValues` for all topics, and manually match the merged/combined topic +} + +func CreateDefinition(contract common.Address, topic1 []byte, topic2 []byte, topic3 []byte, amount int64, target []byte) EventTriggerDefinition { + definition := EventTriggerDefinition{ + Contract: contract, + Signature: EvtSignature{long: TestEvtSigFull}, + Conditions: []Condition{ + { + Location: TopicData{ + number: 1, + }, + Constraint: MatchConstraint{ + target: topic1, + }, + }, + { + Location: TopicData{ + number: 3, + }, + Constraint: MatchConstraint{ + target: topic3, + }, + }, + { + Location: OffsetData{ + argnumber: 0, + complex: false, + }, + Constraint: NumConstraint{ + op: GTE, + target: big.NewInt(amount), + }, + }, + { + Location: OffsetData{ + argnumber: 1, + complex: true, + }, + Constraint: MatchConstraint{ + target: target, + }, + }, + }, + } + return definition +} + +func TestEvtEventTriggerDefinition(t *testing.T) { + setup, err := SetupAndDeploy() + assert.NilError(t, err, "error during setup") + + senderAddr := crypto.PubkeyToAddress(setup.key.PublicKey) + zeroAddr := common.HexToAddress("0x00000000000000000000000000000000") + fiveAddr := common.HexToAddress("0x00000000000000000000000000000005") + amount := int64(1) + // stringMatch := []byte("Lets see how long this string can get and what it will look like in the data, I feel like I need to keep going for a bit........") + stringMatch := []byte("short") + + definition := CreateDefinition(setup.erc20Address, WordPad(senderAddr.Bytes()), nil, WordPad(fiveAddr.Bytes()), int64(1), stringMatch) + assert.Check(t, len(definition.Conditions) == 4, "something went wrong") + f := definition.ToFilterQuery() + assert.Check(t, len(f.Topics) > 0, "no filterquery") + + ERC20Transfer(t, setup, senderAddr, setup.erc20Address, amount) + + checkTopics := true + + logs, err := setup.backend.Client().FilterLogs(context.Background(), f) + assert.NilError(t, err, "error using filter query") + assert.Check(t, len(logs) == 1, "filter did not match") + for _, elog := range logs { + assert.Check(t, definition.Match(elog, checkTopics) == true, "did not match %v", elog.Data) + } + // mismatch on topic2 + ERC20Transfer(t, setup, senderAddr, zeroAddr, 0) + + latest, err := setup.backend.Client().BlockNumber(context.Background()) + assert.NilError(t, err, "no latest block number") + f.FromBlock = big.NewInt(int64(latest)) + f.ToBlock = big.NewInt(int64(latest)) + + logs, err = setup.backend.Client().FilterLogs(context.Background(), f) + assert.NilError(t, err, "error using filter query") + for _, elog := range logs { + assert.Check(t, definition.Match(elog, checkTopics) == false, "did match %v", elog.Data) + } + // mismatch on topic2 -- we should not find the event!) + definition.Conditions = append(definition.Conditions, Condition{ + Location: TopicData{ + number: 2, + }, + Constraint: MatchConstraint{ + target: WordPad(senderAddr.Bytes()), + }, + }) + overspecific := definition.ToFilterQuery() + ERC20Transfer(t, setup, senderAddr, zeroAddr, amount) + + latest, err = setup.backend.Client().BlockNumber(context.Background()) + assert.NilError(t, err, "no latest block number") + f.FromBlock = big.NewInt(int64(latest)) + f.ToBlock = big.NewInt(int64(latest)) + + logs, err = setup.backend.Client().FilterLogs(context.Background(), overspecific) + assert.NilError(t, err, "error using filter query") + assert.Check(t, len(logs) == 0, "event filter query incorrect") + + // mismatch on amount + ERC20Transfer(t, setup, senderAddr, setup.erc20Address, 0) + + latest, err = setup.backend.Client().BlockNumber(context.Background()) + assert.NilError(t, err, "no latest block number") + f.FromBlock = big.NewInt(int64(latest)) + f.ToBlock = big.NewInt(int64(latest)) + + logs, err = setup.backend.Client().FilterLogs(context.Background(), f) + assert.NilError(t, err, "error using filter query") + for _, elog := range logs { + assert.Check(t, definition.Match(elog, checkTopics) == false, "did match %v", elog.Data) + } + + RegisterTrigger(t, setup, definition) +} + +func TestEvtNumConstraintTest(t *testing.T) { + lt1 := NumConstraint{ + LT, + big.NewInt(1), + } + assert.Check(t, lt1.Test(big.NewInt(0)) == true, "wrong result") + assert.Check(t, lt1.Test(big.NewInt(1)) == false, "wrong result") + assert.Check(t, lt1.Test(big.NewInt(2)) == false, "wrong result") + + lte1 := NumConstraint{ + LTE, + big.NewInt(1), + } + assert.Check(t, lte1.Test(big.NewInt(0)) == true, "wrong result") + assert.Check(t, lte1.Test(big.NewInt(1)) == true, "wrong result") + assert.Check(t, lte1.Test(big.NewInt(2)) == false, "wrong result") + + eq1 := NumConstraint{ + EQ, + big.NewInt(1), + } + assert.Check(t, eq1.Test(big.NewInt(0)) == false, "wrong result") + assert.Check(t, eq1.Test(big.NewInt(1)) == true, "wrong result") + assert.Check(t, eq1.Test(big.NewInt(2)) == false, "wrong result") + + gte1 := NumConstraint{ + GTE, + big.NewInt(1), + } + assert.Check(t, gte1.Test(big.NewInt(0)) == false, "wrong result") + assert.Check(t, gte1.Test(big.NewInt(1)) == true, "wrong result") + assert.Check(t, gte1.Test(big.NewInt(2)) == true, "wrong result") + + gt1 := NumConstraint{ + GT, + big.NewInt(1), + } + assert.Check(t, gt1.Test(big.NewInt(0)) == false, "wrong result") + assert.Check(t, gt1.Test(big.NewInt(1)) == false, "wrong result") + assert.Check(t, gt1.Test(big.NewInt(2)) == true, "wrong result") +} + +func TestEvtRegistry(t *testing.T) { + setup, err := SetupAndDeploy() + assert.NilError(t, err, "failed setup and deploy") + + assert.Check(t, setup.backend != nil, "setup is nil") + def := CreateDefinition( + setup.erc20Address, + WordPad(crypto.PubkeyToAddress(setup.key.PublicKey).Bytes()), + WordPad(crypto.PubkeyToAddress(setup.key.PublicKey).Bytes()), + WordPad(crypto.PubkeyToAddress(setup.key.PublicKey).Bytes()), + 1, []byte("short")) + RegisterTrigger(t, setup, def) + + ser := def.MarshalBytes() + + de := EventTriggerDefinition{} + + de.UnmarshalBytes(ser) + round := de.MarshalBytes() + assert.Check(t, deepEqual(ser, round), "roundtrip failed\n%v\n%v", ser, de.MarshalBytes()) + + logs, err := setup.triggerContract.FilterEventTriggerRegistered(&bind.FilterOpts{ + Start: uint64(0), + End: nil, + Context: context.Background(), + }, + []uint64{1}, + ) + for logs.Next() { + x := logs.Event.TriggerDefinition + assert.Check(t, deepEqual(ser, x), "serialization mismatch") + } + var newConditions []Condition + for _, cond := range def.Conditions { + _, ok := cond.Constraint.(NumConstraint) + if !ok { + newConditions = append(newConditions, cond) + } + } + def.Conditions = newConditions + shorter := def.MarshalBytes() + assert.Check(t, !deepEqual(shorter, ser), "we lost a constraint") +} + +func deepEqual(a, b [][]byte) bool { + if len(a) != len(b) { + return false + } + for i, ar := range a { + if len(b[i]) != len(ar) { + return false + } + for j, v := range ar { + if b[i][j] != v { + return false + } + } + } + return true +} diff --git a/rolling-shutter/keyperimpl/shutterservice/help/.tool-versions b/rolling-shutter/keyperimpl/shutterservice/help/.tool-versions new file mode 100644 index 00000000..5225c33e --- /dev/null +++ b/rolling-shutter/keyperimpl/shutterservice/help/.tool-versions @@ -0,0 +1,2 @@ +golang 1.21.4 +solidity 0.8.28 diff --git a/rolling-shutter/keyperimpl/shutterservice/help/Context.sol b/rolling-shutter/keyperimpl/shutterservice/help/Context.sol new file mode 100644 index 00000000..9037dcd1 --- /dev/null +++ b/rolling-shutter/keyperimpl/shutterservice/help/Context.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Provides information about the current execution context, including the + * sender of the transaction and its data. While these are generally available + * via msg.sender and msg.data, they should not be accessed in such a direct + * manner, since when dealing with meta-transactions the account sending and + * paying for execution may not be the actual sender (as far as an application + * is concerned). + * + * This contract is only required for intermediate, library-like contracts. + */ +abstract contract Context { + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } +} diff --git a/rolling-shutter/keyperimpl/shutterservice/help/Ownable.sol b/rolling-shutter/keyperimpl/shutterservice/help/Ownable.sol new file mode 100644 index 00000000..5d2d1bf5 --- /dev/null +++ b/rolling-shutter/keyperimpl/shutterservice/help/Ownable.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) + +pragma solidity ^0.8.20; + +import {Context} from "./Context.sol"; + +/** + * @dev Contract module which provides a basic access control mechanism, where + * there is an account (an owner) that can be granted exclusive access to + * specific functions. + * + * The initial owner is set to the address provided by the deployer. This can + * later be changed with {transferOwnership}. + * + * This module is used through inheritance. It will make available the modifier + * `onlyOwner`, which can be applied to your functions to restrict their use to + * the owner. + */ +abstract contract Ownable is Context { + address private _owner; + + /** + * @dev The caller account is not authorized to perform an operation. + */ + error OwnableUnauthorizedAccount(address account); + + /** + * @dev The owner is not a valid owner account. (eg. `address(0)`) + */ + error OwnableInvalidOwner(address owner); + + event OwnershipTransferred( + address indexed previousOwner, + address indexed newOwner + ); + + /** + * @dev Initializes the contract setting the address provided by the deployer as the initial owner. + */ + constructor(address initialOwner) { + if (initialOwner == address(0)) { + revert OwnableInvalidOwner(address(0)); + } + _transferOwnership(initialOwner); + } + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + _checkOwner(); + _; + } + + /** + * @dev Returns the address of the current owner. + */ + function owner() public view virtual returns (address) { + return _owner; + } + + /** + * @dev Throws if the sender is not the owner. + */ + function _checkOwner() internal view virtual { + if (owner() != _msgSender()) { + revert OwnableUnauthorizedAccount(_msgSender()); + } + } + + /** + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions. Can only be called by the current owner. + * + * NOTE: Renouncing ownership will leave the contract without an owner, + * thereby disabling any functionality that is only available to the owner. + */ + function renounceOwnership() public virtual onlyOwner { + _transferOwnership(address(0)); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. + */ + function transferOwnership(address newOwner) public virtual onlyOwner { + if (newOwner == address(0)) { + revert OwnableInvalidOwner(address(0)); + } + _transferOwnership(newOwner); + } + + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Internal function without access restriction. + */ + function _transferOwnership(address newOwner) internal virtual { + address oldOwner = _owner; + _owner = newOwner; + emit OwnershipTransferred(oldOwner, newOwner); + } +} diff --git a/rolling-shutter/keyperimpl/shutterservice/help/ShutterEventTrigger.sol b/rolling-shutter/keyperimpl/shutterservice/help/ShutterEventTrigger.sol new file mode 100644 index 00000000..ed46d532 --- /dev/null +++ b/rolling-shutter/keyperimpl/shutterservice/help/ShutterEventTrigger.sol @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.28; + +import "./Ownable.sol"; + +/** + * @title ShutterRegistry + * @dev A contract for managing the registration of identities with timestamps, ensuring unique and future-dated registrations. + * Inherits from OpenZeppelin's Ownable contract to enable ownership-based access control. + */ +contract ShutterRegistry is Ownable { + // Custom error for when an identity is already registered. + error AlreadyRegistered(); + + // Custom error for when a provided timestamp is in the past. + error TimestampInThePast(); + + // Custom error for when a identityPrefix provided is empty. + error InvalidIdentityPrefix(); + + // Custom error for when the registration ttl is lower than already registered. + error TTLTooShort(); + + struct EventTriggerRegistration { + uint64 eon; + uint64 ttl; + bytes32 triggerDefinitionHash; + } + /** + * @dev Mapping to store registration data for each identity. + * The identity is represented as a `bytes32` hash and mapped to the EventTriggerRegistration. + */ + + mapping(bytes32 identity => EventTriggerRegistration) public registrations; + + /** + * @dev Emitted when a new event trigger identity is successfully registered. + * @param eon The eon associated with the identity. + * @param identityPrefix The raw prefix input used to derive the registered identity hash. + * @param sender The address of the account that performed the registration. + * @param triggerDefinition The eventTriggerDefinition associated with the registered identity. + * @param ttl The blockNumber after which the eventTrigger can be ignored by keypers. + */ + event EventTriggerRegistered( + uint64 indexed eon, + bytes32 identityPrefix, + address sender, + bytes[] triggerDefinition, + uint64 ttl + ); + + /** + * @dev Initializes the contract and assigns ownership to the deployer. + */ + constructor() Ownable(msg.sender) {} + + /** + * @notice Registers a new identity with a specified eventTriggerDefinition and eon. + * @dev The identity is derived by hashing the provided `identityPrefix` concatenated with the sender's address. + * @param eon The eon associated with the identity. + * @param identityPrefix The input used to derive the identity hash. + * @param triggerDefinition The eventTriggerDefinition. + * @param ttl A block number in the future after which the trigger can be ignored by keypers. + * @custom:requirements + * - The identity must not already be registered. + * - The provided ttl block number must not be in the past. + */ + function register( + uint64 eon, + bytes32 identityPrefix, + bytes[] memory triggerDefinition, + uint64 ttl + ) external { + // Ensure the timestamp is not in the past. + require(ttl >= block.number, TimestampInThePast()); + + // Ensure identityPrefix passed in correct. + require(identityPrefix != bytes32(0), InvalidIdentityPrefix()); + + // Generate the identity hash from the provided prefix and the sender's address. + bytes32 identity = keccak256( + abi.encodePacked(identityPrefix, msg.sender) + ); + EventTriggerRegistration storage registrationData = registrations[ + identity + ]; + // Ensure no one is trying to decrease ttl. + require(registrationData.ttl < ttl, TTLTooShort()); + + if (registrationData.ttl != 0) { + require( + keccak256(abi.encode(triggerDefinition)) == + registrationData.triggerDefinitionHash, + AlreadyRegistered() + ); + } + + // store the (maybe renewed) registration data; + registrationData.ttl = ttl; + registrationData.eon = eon; + registrationData.triggerDefinitionHash = keccak256( + abi.encode(triggerDefinition) + ); + + // Emit the EventTriggerRegistered event. + emit EventTriggerRegistered( + eon, + identityPrefix, + msg.sender, + triggerDefinition, + ttl + ); + } +} diff --git a/rolling-shutter/keyperimpl/shutterservice/help/do_it.sh b/rolling-shutter/keyperimpl/shutterservice/help/do_it.sh new file mode 100755 index 00000000..3d0b2fbb --- /dev/null +++ b/rolling-shutter/keyperimpl/shutterservice/help/do_it.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +solc --combined-json abi,asm,ast,bin,bin-runtime,devdoc,function-debug,function-debug-runtime,generated-sources,generated-sources-runtime,hashes,metadata,opcodes,srcmap,srcmap-runtime,storage-layout,userdoc erc20.sol >erc20.combined.json + +abigen --combined-json erc20.combined.json --pkg help --out erc20bindings.go + +solc --combined-json abi,asm,ast,bin,bin-runtime,devdoc,function-debug,function-debug-runtime,generated-sources,generated-sources-runtime,hashes,metadata,opcodes,srcmap,srcmap-runtime,storage-layout,userdoc ShutterEventTrigger.sol >eventtrigger.combined.json + +abigen --combined-json eventtrigger.combined.json --pkg help --out eventtriggerbindings.go diff --git a/rolling-shutter/keyperimpl/shutterservice/help/erc20.sol b/rolling-shutter/keyperimpl/shutterservice/help/erc20.sol new file mode 100644 index 00000000..c7871e8a --- /dev/null +++ b/rolling-shutter/keyperimpl/shutterservice/help/erc20.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IERC20 { + function totalSupply() external view returns (uint256); + + function balanceOf(address account) external view returns (uint256); + + function allowance( + address owner, + address spender + ) external view returns (uint256); + + function transfer( + address recipient, + uint256 amount + ) external returns (bool); + + function approve(address spender, uint256 amount) external returns (bool); + + function transferFrom( + address sender, + address recipient, + uint256 amount + ) external returns (bool); + + event Transfer( + address indexed from, + address indexed to, + address indexed notify, + uint256 value, + string foobar + ); + event Approval( + address indexed owner, + address indexed spender, + uint256 value + ); +} + +contract ERC20Basic is IERC20 { + string public constant name = "ERC20Basic"; + string public constant symbol = "ERC"; + uint8 public constant decimals = 18; + + mapping(address => uint256) balances; + + mapping(address => mapping(address => uint256)) allowed; + + uint256 totalSupply_ = 10 ether; + + constructor() { + balances[msg.sender] = totalSupply_; + } + + function totalSupply() public view override returns (uint256) { + return totalSupply_; + } + + function balanceOf( + address tokenOwner + ) public view override returns (uint256) { + return balances[tokenOwner]; + } + + function transfer( + address receiver, + uint256 numTokens + ) public override returns (bool) { + require(numTokens <= balances[msg.sender]); + balances[msg.sender] = balances[msg.sender] - numTokens; + balances[receiver] = balances[receiver] + numTokens; + emit Transfer(msg.sender, receiver, address(5), numTokens, "short"); + return true; + } + + function approve( + address delegate, + uint256 numTokens + ) public override returns (bool) { + allowed[msg.sender][delegate] = numTokens; + emit Approval(msg.sender, delegate, numTokens); + return true; + } + + function allowance( + address owner, + address delegate + ) public view override returns (uint) { + return allowed[owner][delegate]; + } + + function transferFrom( + address owner, + address buyer, + uint256 numTokens + ) public override returns (bool) { + require(numTokens <= balances[owner]); + require(numTokens <= allowed[owner][msg.sender]); + + balances[owner] = balances[owner] - numTokens; + allowed[owner][msg.sender] = allowed[owner][msg.sender] + numTokens; + balances[buyer] = balances[buyer] + numTokens; + emit Transfer( + owner, + buyer, + address(6), + numTokens, + "Transfer from is short" + ); + return true; + } +} diff --git a/rolling-shutter/keyperimpl/shutterservice/help/erc20bindings.go b/rolling-shutter/keyperimpl/shutterservice/help/erc20bindings.go new file mode 100644 index 00000000..ee80117e --- /dev/null +++ b/rolling-shutter/keyperimpl/shutterservice/help/erc20bindings.go @@ -0,0 +1,1396 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package help + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ERC20BasicMetaData contains all meta data concerning the ERC20Basic contract. +var ERC20BasicMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"notify\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"foobar\",\"type\":\"string\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"numTokens\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenOwner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"numTokens\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"buyer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"numTokens\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "dd62ed3e": "allowance(address,address)", + "095ea7b3": "approve(address,uint256)", + "70a08231": "balanceOf(address)", + "313ce567": "decimals()", + "06fdde03": "name()", + "95d89b41": "symbol()", + "18160ddd": "totalSupply()", + "a9059cbb": "transfer(address,uint256)", + "23b872dd": "transferFrom(address,address,uint256)", + }, + Bin: "0x6080604052678ac7230489e80000600255348015601a575f5ffd5b506002545f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550610dd28061006b5f395ff3fe608060405234801561000f575f5ffd5b5060043610610091575f3560e01c8063313ce56711610064578063313ce5671461013157806370a082311461014f57806395d89b411461017f578063a9059cbb1461019d578063dd62ed3e146101cd57610091565b806306fdde0314610095578063095ea7b3146100b357806318160ddd146100e357806323b872dd14610101575b5f5ffd5b61009d6101fd565b6040516100aa91906109e6565b60405180910390f35b6100cd60048036038101906100c89190610a97565b610236565b6040516100da9190610aef565b60405180910390f35b6100eb610323565b6040516100f89190610b17565b60405180910390f35b61011b60048036038101906101169190610b30565b61032c565b6040516101289190610aef565b60405180910390f35b610139610691565b6040516101469190610b9b565b60405180910390f35b61016960048036038101906101649190610bb4565b610696565b6040516101769190610b17565b60405180910390f35b6101876106db565b60405161019491906109e6565b60405180910390f35b6101b760048036038101906101b29190610a97565b610714565b6040516101c49190610aef565b60405180910390f35b6101e760048036038101906101e29190610bdf565b6108f4565b6040516101f49190610b17565b60405180910390f35b6040518060400160405280600a81526020017f455243323042617369630000000000000000000000000000000000000000000081525081565b5f8160015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516103119190610b17565b60405180910390a36001905092915050565b5f600254905090565b5f5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054821115610375575f5ffd5b60015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20548211156103f9575f5ffd5b815f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20546104419190610c4a565b5f5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20546105059190610c7d565b60015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550815f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20546105c99190610c7d565b5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550600673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167ff8ffa2f4cc3cb642240a588faa304203a1f404d3805f4ab5eb30fcd1f54213d18560405161067e9190610cfa565b60405180910390a4600190509392505050565b601281565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6040518060400160405280600381526020017f455243000000000000000000000000000000000000000000000000000000000081525081565b5f5f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205482111561075d575f5ffd5b815f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20546107a59190610c4a565b5f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550815f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205461082d9190610c7d565b5f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550600573ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ff8ffa2f4cc3cb642240a588faa304203a1f404d3805f4ab5eb30fcd1f54213d1856040516108e29190610d70565b60405180910390a46001905092915050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6109b882610976565b6109c28185610980565b93506109d2818560208601610990565b6109db8161099e565b840191505092915050565b5f6020820190508181035f8301526109fe81846109ae565b905092915050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610a3382610a0a565b9050919050565b610a4381610a29565b8114610a4d575f5ffd5b50565b5f81359050610a5e81610a3a565b92915050565b5f819050919050565b610a7681610a64565b8114610a80575f5ffd5b50565b5f81359050610a9181610a6d565b92915050565b5f5f60408385031215610aad57610aac610a06565b5b5f610aba85828601610a50565b9250506020610acb85828601610a83565b9150509250929050565b5f8115159050919050565b610ae981610ad5565b82525050565b5f602082019050610b025f830184610ae0565b92915050565b610b1181610a64565b82525050565b5f602082019050610b2a5f830184610b08565b92915050565b5f5f5f60608486031215610b4757610b46610a06565b5b5f610b5486828701610a50565b9350506020610b6586828701610a50565b9250506040610b7686828701610a83565b9150509250925092565b5f60ff82169050919050565b610b9581610b80565b82525050565b5f602082019050610bae5f830184610b8c565b92915050565b5f60208284031215610bc957610bc8610a06565b5b5f610bd684828501610a50565b91505092915050565b5f5f60408385031215610bf557610bf4610a06565b5b5f610c0285828601610a50565b9250506020610c1385828601610a50565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610c5482610a64565b9150610c5f83610a64565b9250828203905081811115610c7757610c76610c1d565b5b92915050565b5f610c8782610a64565b9150610c9283610a64565b9250828201905080821115610caa57610ca9610c1d565b5b92915050565b7f5472616e736665722066726f6d2069732073686f7274000000000000000000005f82015250565b5f610ce4601683610980565b9150610cef82610cb0565b602082019050919050565b5f604082019050610d0d5f830184610b08565b8181036020830152610d1e81610cd8565b905092915050565b7f73686f72740000000000000000000000000000000000000000000000000000005f82015250565b5f610d5a600583610980565b9150610d6582610d26565b602082019050919050565b5f604082019050610d835f830184610b08565b8181036020830152610d9481610d4e565b90509291505056fea2646970667358221220fc173f7765ad08b47e3cc719d32c496d9d1da3a9f1819bd36f0ae2e4006cc80e64736f6c634300081c0033", +} + +// ERC20BasicABI is the input ABI used to generate the binding from. +// Deprecated: Use ERC20BasicMetaData.ABI instead. +var ERC20BasicABI = ERC20BasicMetaData.ABI + +// Deprecated: Use ERC20BasicMetaData.Sigs instead. +// ERC20BasicFuncSigs maps the 4-byte function signature to its string representation. +var ERC20BasicFuncSigs = ERC20BasicMetaData.Sigs + +// ERC20BasicBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ERC20BasicMetaData.Bin instead. +var ERC20BasicBin = ERC20BasicMetaData.Bin + +// DeployERC20Basic deploys a new Ethereum contract, binding an instance of ERC20Basic to it. +func DeployERC20Basic(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ERC20Basic, error) { + parsed, err := ERC20BasicMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ERC20BasicBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ERC20Basic{ERC20BasicCaller: ERC20BasicCaller{contract: contract}, ERC20BasicTransactor: ERC20BasicTransactor{contract: contract}, ERC20BasicFilterer: ERC20BasicFilterer{contract: contract}}, nil +} + +// ERC20Basic is an auto generated Go binding around an Ethereum contract. +type ERC20Basic struct { + ERC20BasicCaller // Read-only binding to the contract + ERC20BasicTransactor // Write-only binding to the contract + ERC20BasicFilterer // Log filterer for contract events +} + +// ERC20BasicCaller is an auto generated read-only Go binding around an Ethereum contract. +type ERC20BasicCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20BasicTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ERC20BasicTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20BasicFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ERC20BasicFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20BasicSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ERC20BasicSession struct { + Contract *ERC20Basic // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20BasicCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ERC20BasicCallerSession struct { + Contract *ERC20BasicCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ERC20BasicTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ERC20BasicTransactorSession struct { + Contract *ERC20BasicTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20BasicRaw is an auto generated low-level Go binding around an Ethereum contract. +type ERC20BasicRaw struct { + Contract *ERC20Basic // Generic contract binding to access the raw methods on +} + +// ERC20BasicCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ERC20BasicCallerRaw struct { + Contract *ERC20BasicCaller // Generic read-only contract binding to access the raw methods on +} + +// ERC20BasicTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ERC20BasicTransactorRaw struct { + Contract *ERC20BasicTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewERC20Basic creates a new instance of ERC20Basic, bound to a specific deployed contract. +func NewERC20Basic(address common.Address, backend bind.ContractBackend) (*ERC20Basic, error) { + contract, err := bindERC20Basic(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ERC20Basic{ERC20BasicCaller: ERC20BasicCaller{contract: contract}, ERC20BasicTransactor: ERC20BasicTransactor{contract: contract}, ERC20BasicFilterer: ERC20BasicFilterer{contract: contract}}, nil +} + +// NewERC20BasicCaller creates a new read-only instance of ERC20Basic, bound to a specific deployed contract. +func NewERC20BasicCaller(address common.Address, caller bind.ContractCaller) (*ERC20BasicCaller, error) { + contract, err := bindERC20Basic(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ERC20BasicCaller{contract: contract}, nil +} + +// NewERC20BasicTransactor creates a new write-only instance of ERC20Basic, bound to a specific deployed contract. +func NewERC20BasicTransactor(address common.Address, transactor bind.ContractTransactor) (*ERC20BasicTransactor, error) { + contract, err := bindERC20Basic(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ERC20BasicTransactor{contract: contract}, nil +} + +// NewERC20BasicFilterer creates a new log filterer instance of ERC20Basic, bound to a specific deployed contract. +func NewERC20BasicFilterer(address common.Address, filterer bind.ContractFilterer) (*ERC20BasicFilterer, error) { + contract, err := bindERC20Basic(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ERC20BasicFilterer{contract: contract}, nil +} + +// bindERC20Basic binds a generic wrapper to an already deployed contract. +func bindERC20Basic(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ERC20BasicMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20Basic *ERC20BasicRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20Basic.Contract.ERC20BasicCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20Basic *ERC20BasicRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20Basic.Contract.ERC20BasicTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20Basic *ERC20BasicRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20Basic.Contract.ERC20BasicTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20Basic *ERC20BasicCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20Basic.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20Basic *ERC20BasicTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20Basic.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20Basic *ERC20BasicTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20Basic.Contract.contract.Transact(opts, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address delegate) view returns(uint256) +func (_ERC20Basic *ERC20BasicCaller) Allowance(opts *bind.CallOpts, owner common.Address, delegate common.Address) (*big.Int, error) { + var out []interface{} + err := _ERC20Basic.contract.Call(opts, &out, "allowance", owner, delegate) + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address delegate) view returns(uint256) +func (_ERC20Basic *ERC20BasicSession) Allowance(owner common.Address, delegate common.Address) (*big.Int, error) { + return _ERC20Basic.Contract.Allowance(&_ERC20Basic.CallOpts, owner, delegate) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address delegate) view returns(uint256) +func (_ERC20Basic *ERC20BasicCallerSession) Allowance(owner common.Address, delegate common.Address) (*big.Int, error) { + return _ERC20Basic.Contract.Allowance(&_ERC20Basic.CallOpts, owner, delegate) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address tokenOwner) view returns(uint256) +func (_ERC20Basic *ERC20BasicCaller) BalanceOf(opts *bind.CallOpts, tokenOwner common.Address) (*big.Int, error) { + var out []interface{} + err := _ERC20Basic.contract.Call(opts, &out, "balanceOf", tokenOwner) + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address tokenOwner) view returns(uint256) +func (_ERC20Basic *ERC20BasicSession) BalanceOf(tokenOwner common.Address) (*big.Int, error) { + return _ERC20Basic.Contract.BalanceOf(&_ERC20Basic.CallOpts, tokenOwner) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address tokenOwner) view returns(uint256) +func (_ERC20Basic *ERC20BasicCallerSession) BalanceOf(tokenOwner common.Address) (*big.Int, error) { + return _ERC20Basic.Contract.BalanceOf(&_ERC20Basic.CallOpts, tokenOwner) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ERC20Basic *ERC20BasicCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ERC20Basic.contract.Call(opts, &out, "decimals") + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ERC20Basic *ERC20BasicSession) Decimals() (uint8, error) { + return _ERC20Basic.Contract.Decimals(&_ERC20Basic.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ERC20Basic *ERC20BasicCallerSession) Decimals() (uint8, error) { + return _ERC20Basic.Contract.Decimals(&_ERC20Basic.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ERC20Basic *ERC20BasicCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ERC20Basic.contract.Call(opts, &out, "name") + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ERC20Basic *ERC20BasicSession) Name() (string, error) { + return _ERC20Basic.Contract.Name(&_ERC20Basic.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ERC20Basic *ERC20BasicCallerSession) Name() (string, error) { + return _ERC20Basic.Contract.Name(&_ERC20Basic.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ERC20Basic *ERC20BasicCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ERC20Basic.contract.Call(opts, &out, "symbol") + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ERC20Basic *ERC20BasicSession) Symbol() (string, error) { + return _ERC20Basic.Contract.Symbol(&_ERC20Basic.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ERC20Basic *ERC20BasicCallerSession) Symbol() (string, error) { + return _ERC20Basic.Contract.Symbol(&_ERC20Basic.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ERC20Basic *ERC20BasicCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20Basic.contract.Call(opts, &out, "totalSupply") + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ERC20Basic *ERC20BasicSession) TotalSupply() (*big.Int, error) { + return _ERC20Basic.Contract.TotalSupply(&_ERC20Basic.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ERC20Basic *ERC20BasicCallerSession) TotalSupply() (*big.Int, error) { + return _ERC20Basic.Contract.TotalSupply(&_ERC20Basic.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address delegate, uint256 numTokens) returns(bool) +func (_ERC20Basic *ERC20BasicTransactor) Approve(opts *bind.TransactOpts, delegate common.Address, numTokens *big.Int) (*types.Transaction, error) { + return _ERC20Basic.contract.Transact(opts, "approve", delegate, numTokens) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address delegate, uint256 numTokens) returns(bool) +func (_ERC20Basic *ERC20BasicSession) Approve(delegate common.Address, numTokens *big.Int) (*types.Transaction, error) { + return _ERC20Basic.Contract.Approve(&_ERC20Basic.TransactOpts, delegate, numTokens) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address delegate, uint256 numTokens) returns(bool) +func (_ERC20Basic *ERC20BasicTransactorSession) Approve(delegate common.Address, numTokens *big.Int) (*types.Transaction, error) { + return _ERC20Basic.Contract.Approve(&_ERC20Basic.TransactOpts, delegate, numTokens) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address receiver, uint256 numTokens) returns(bool) +func (_ERC20Basic *ERC20BasicTransactor) Transfer(opts *bind.TransactOpts, receiver common.Address, numTokens *big.Int) (*types.Transaction, error) { + return _ERC20Basic.contract.Transact(opts, "transfer", receiver, numTokens) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address receiver, uint256 numTokens) returns(bool) +func (_ERC20Basic *ERC20BasicSession) Transfer(receiver common.Address, numTokens *big.Int) (*types.Transaction, error) { + return _ERC20Basic.Contract.Transfer(&_ERC20Basic.TransactOpts, receiver, numTokens) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address receiver, uint256 numTokens) returns(bool) +func (_ERC20Basic *ERC20BasicTransactorSession) Transfer(receiver common.Address, numTokens *big.Int) (*types.Transaction, error) { + return _ERC20Basic.Contract.Transfer(&_ERC20Basic.TransactOpts, receiver, numTokens) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address owner, address buyer, uint256 numTokens) returns(bool) +func (_ERC20Basic *ERC20BasicTransactor) TransferFrom(opts *bind.TransactOpts, owner common.Address, buyer common.Address, numTokens *big.Int) (*types.Transaction, error) { + return _ERC20Basic.contract.Transact(opts, "transferFrom", owner, buyer, numTokens) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address owner, address buyer, uint256 numTokens) returns(bool) +func (_ERC20Basic *ERC20BasicSession) TransferFrom(owner common.Address, buyer common.Address, numTokens *big.Int) (*types.Transaction, error) { + return _ERC20Basic.Contract.TransferFrom(&_ERC20Basic.TransactOpts, owner, buyer, numTokens) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address owner, address buyer, uint256 numTokens) returns(bool) +func (_ERC20Basic *ERC20BasicTransactorSession) TransferFrom(owner common.Address, buyer common.Address, numTokens *big.Int) (*types.Transaction, error) { + return _ERC20Basic.Contract.TransferFrom(&_ERC20Basic.TransactOpts, owner, buyer, numTokens) +} + +// ERC20BasicApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the ERC20Basic contract. +type ERC20BasicApprovalIterator struct { + Event *ERC20BasicApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20BasicApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20BasicApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20BasicApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20BasicApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20BasicApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20BasicApproval represents a Approval event raised by the ERC20Basic contract. +type ERC20BasicApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ERC20Basic *ERC20BasicFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ERC20BasicApprovalIterator, error) { + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ERC20Basic.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &ERC20BasicApprovalIterator{contract: _ERC20Basic.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ERC20Basic *ERC20BasicFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *ERC20BasicApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ERC20Basic.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20BasicApproval) + if err := _ERC20Basic.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ERC20Basic *ERC20BasicFilterer) ParseApproval(log types.Log) (*ERC20BasicApproval, error) { + event := new(ERC20BasicApproval) + if err := _ERC20Basic.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20BasicTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ERC20Basic contract. +type ERC20BasicTransferIterator struct { + Event *ERC20BasicTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20BasicTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20BasicTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20BasicTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20BasicTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20BasicTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20BasicTransfer represents a Transfer event raised by the ERC20Basic contract. +type ERC20BasicTransfer struct { + From common.Address + To common.Address + Notify common.Address + Value *big.Int + Foobar string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xf8ffa2f4cc3cb642240a588faa304203a1f404d3805f4ab5eb30fcd1f54213d1. +// +// Solidity: event Transfer(address indexed from, address indexed to, address indexed notify, uint256 value, string foobar) +func (_ERC20Basic *ERC20BasicFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address, notify []common.Address) (*ERC20BasicTransferIterator, error) { + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + var notifyRule []interface{} + for _, notifyItem := range notify { + notifyRule = append(notifyRule, notifyItem) + } + + logs, sub, err := _ERC20Basic.contract.FilterLogs(opts, "Transfer", fromRule, toRule, notifyRule) + if err != nil { + return nil, err + } + return &ERC20BasicTransferIterator{contract: _ERC20Basic.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xf8ffa2f4cc3cb642240a588faa304203a1f404d3805f4ab5eb30fcd1f54213d1. +// +// Solidity: event Transfer(address indexed from, address indexed to, address indexed notify, uint256 value, string foobar) +func (_ERC20Basic *ERC20BasicFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ERC20BasicTransfer, from []common.Address, to []common.Address, notify []common.Address) (event.Subscription, error) { + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + var notifyRule []interface{} + for _, notifyItem := range notify { + notifyRule = append(notifyRule, notifyItem) + } + + logs, sub, err := _ERC20Basic.contract.WatchLogs(opts, "Transfer", fromRule, toRule, notifyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20BasicTransfer) + if err := _ERC20Basic.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xf8ffa2f4cc3cb642240a588faa304203a1f404d3805f4ab5eb30fcd1f54213d1. +// +// Solidity: event Transfer(address indexed from, address indexed to, address indexed notify, uint256 value, string foobar) +func (_ERC20Basic *ERC20BasicFilterer) ParseTransfer(log types.Log) (*ERC20BasicTransfer, error) { + event := new(ERC20BasicTransfer) + if err := _ERC20Basic.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IERC20MetaData contains all meta data concerning the IERC20 contract. +var IERC20MetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"notify\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"foobar\",\"type\":\"string\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "dd62ed3e": "allowance(address,address)", + "095ea7b3": "approve(address,uint256)", + "70a08231": "balanceOf(address)", + "18160ddd": "totalSupply()", + "a9059cbb": "transfer(address,uint256)", + "23b872dd": "transferFrom(address,address,uint256)", + }, +} + +// IERC20ABI is the input ABI used to generate the binding from. +// Deprecated: Use IERC20MetaData.ABI instead. +var IERC20ABI = IERC20MetaData.ABI + +// Deprecated: Use IERC20MetaData.Sigs instead. +// IERC20FuncSigs maps the 4-byte function signature to its string representation. +var IERC20FuncSigs = IERC20MetaData.Sigs + +// IERC20 is an auto generated Go binding around an Ethereum contract. +type IERC20 struct { + IERC20Caller // Read-only binding to the contract + IERC20Transactor // Write-only binding to the contract + IERC20Filterer // Log filterer for contract events +} + +// IERC20Caller is an auto generated read-only Go binding around an Ethereum contract. +type IERC20Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IERC20Transactor is an auto generated write-only Go binding around an Ethereum contract. +type IERC20Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IERC20Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IERC20Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IERC20Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type IERC20Session struct { + Contract *IERC20 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IERC20CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type IERC20CallerSession struct { + Contract *IERC20Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// IERC20TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type IERC20TransactorSession struct { + Contract *IERC20Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IERC20Raw is an auto generated low-level Go binding around an Ethereum contract. +type IERC20Raw struct { + Contract *IERC20 // Generic contract binding to access the raw methods on +} + +// IERC20CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IERC20CallerRaw struct { + Contract *IERC20Caller // Generic read-only contract binding to access the raw methods on +} + +// IERC20TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IERC20TransactorRaw struct { + Contract *IERC20Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewIERC20 creates a new instance of IERC20, bound to a specific deployed contract. +func NewIERC20(address common.Address, backend bind.ContractBackend) (*IERC20, error) { + contract, err := bindIERC20(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IERC20{IERC20Caller: IERC20Caller{contract: contract}, IERC20Transactor: IERC20Transactor{contract: contract}, IERC20Filterer: IERC20Filterer{contract: contract}}, nil +} + +// NewIERC20Caller creates a new read-only instance of IERC20, bound to a specific deployed contract. +func NewIERC20Caller(address common.Address, caller bind.ContractCaller) (*IERC20Caller, error) { + contract, err := bindIERC20(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IERC20Caller{contract: contract}, nil +} + +// NewIERC20Transactor creates a new write-only instance of IERC20, bound to a specific deployed contract. +func NewIERC20Transactor(address common.Address, transactor bind.ContractTransactor) (*IERC20Transactor, error) { + contract, err := bindIERC20(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IERC20Transactor{contract: contract}, nil +} + +// NewIERC20Filterer creates a new log filterer instance of IERC20, bound to a specific deployed contract. +func NewIERC20Filterer(address common.Address, filterer bind.ContractFilterer) (*IERC20Filterer, error) { + contract, err := bindIERC20(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IERC20Filterer{contract: contract}, nil +} + +// bindIERC20 binds a generic wrapper to an already deployed contract. +func bindIERC20(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IERC20MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IERC20 *IERC20Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IERC20.Contract.IERC20Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IERC20 *IERC20Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IERC20.Contract.IERC20Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IERC20 *IERC20Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IERC20.Contract.IERC20Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IERC20 *IERC20CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IERC20.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IERC20 *IERC20TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IERC20.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IERC20 *IERC20TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IERC20.Contract.contract.Transact(opts, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_IERC20 *IERC20Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _IERC20.contract.Call(opts, &out, "allowance", owner, spender) + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_IERC20 *IERC20Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _IERC20.Contract.Allowance(&_IERC20.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_IERC20 *IERC20CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _IERC20.Contract.Allowance(&_IERC20.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_IERC20 *IERC20Caller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _IERC20.contract.Call(opts, &out, "balanceOf", account) + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_IERC20 *IERC20Session) BalanceOf(account common.Address) (*big.Int, error) { + return _IERC20.Contract.BalanceOf(&_IERC20.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_IERC20 *IERC20CallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _IERC20.Contract.BalanceOf(&_IERC20.CallOpts, account) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_IERC20 *IERC20Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IERC20.contract.Call(opts, &out, "totalSupply") + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_IERC20 *IERC20Session) TotalSupply() (*big.Int, error) { + return _IERC20.Contract.TotalSupply(&_IERC20.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_IERC20 *IERC20CallerSession) TotalSupply() (*big.Int, error) { + return _IERC20.Contract.TotalSupply(&_IERC20.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_IERC20 *IERC20Transactor) Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _IERC20.contract.Transact(opts, "approve", spender, amount) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_IERC20 *IERC20Session) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.Approve(&_IERC20.TransactOpts, spender, amount) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 amount) returns(bool) +func (_IERC20 *IERC20TransactorSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.Approve(&_IERC20.TransactOpts, spender, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address recipient, uint256 amount) returns(bool) +func (_IERC20 *IERC20Transactor) Transfer(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _IERC20.contract.Transact(opts, "transfer", recipient, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address recipient, uint256 amount) returns(bool) +func (_IERC20 *IERC20Session) Transfer(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.Transfer(&_IERC20.TransactOpts, recipient, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address recipient, uint256 amount) returns(bool) +func (_IERC20 *IERC20TransactorSession) Transfer(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.Transfer(&_IERC20.TransactOpts, recipient, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool) +func (_IERC20 *IERC20Transactor) TransferFrom(opts *bind.TransactOpts, sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _IERC20.contract.Transact(opts, "transferFrom", sender, recipient, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool) +func (_IERC20 *IERC20Session) TransferFrom(sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.TransferFrom(&_IERC20.TransactOpts, sender, recipient, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool) +func (_IERC20 *IERC20TransactorSession) TransferFrom(sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.TransferFrom(&_IERC20.TransactOpts, sender, recipient, amount) +} + +// IERC20ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the IERC20 contract. +type IERC20ApprovalIterator struct { + Event *IERC20Approval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IERC20ApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IERC20Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IERC20Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IERC20ApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IERC20ApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IERC20Approval represents a Approval event raised by the IERC20 contract. +type IERC20Approval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_IERC20 *IERC20Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*IERC20ApprovalIterator, error) { + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _IERC20.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &IERC20ApprovalIterator{contract: _IERC20.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_IERC20 *IERC20Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *IERC20Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _IERC20.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IERC20Approval) + if err := _IERC20.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_IERC20 *IERC20Filterer) ParseApproval(log types.Log) (*IERC20Approval, error) { + event := new(IERC20Approval) + if err := _IERC20.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IERC20TransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the IERC20 contract. +type IERC20TransferIterator struct { + Event *IERC20Transfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IERC20TransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IERC20Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IERC20Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IERC20TransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IERC20TransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IERC20Transfer represents a Transfer event raised by the IERC20 contract. +type IERC20Transfer struct { + From common.Address + To common.Address + Notify common.Address + Value *big.Int + Foobar string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xf8ffa2f4cc3cb642240a588faa304203a1f404d3805f4ab5eb30fcd1f54213d1. +// +// Solidity: event Transfer(address indexed from, address indexed to, address indexed notify, uint256 value, string foobar) +func (_IERC20 *IERC20Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address, notify []common.Address) (*IERC20TransferIterator, error) { + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + var notifyRule []interface{} + for _, notifyItem := range notify { + notifyRule = append(notifyRule, notifyItem) + } + + logs, sub, err := _IERC20.contract.FilterLogs(opts, "Transfer", fromRule, toRule, notifyRule) + if err != nil { + return nil, err + } + return &IERC20TransferIterator{contract: _IERC20.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xf8ffa2f4cc3cb642240a588faa304203a1f404d3805f4ab5eb30fcd1f54213d1. +// +// Solidity: event Transfer(address indexed from, address indexed to, address indexed notify, uint256 value, string foobar) +func (_IERC20 *IERC20Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *IERC20Transfer, from []common.Address, to []common.Address, notify []common.Address) (event.Subscription, error) { + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + var notifyRule []interface{} + for _, notifyItem := range notify { + notifyRule = append(notifyRule, notifyItem) + } + + logs, sub, err := _IERC20.contract.WatchLogs(opts, "Transfer", fromRule, toRule, notifyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IERC20Transfer) + if err := _IERC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xf8ffa2f4cc3cb642240a588faa304203a1f404d3805f4ab5eb30fcd1f54213d1. +// +// Solidity: event Transfer(address indexed from, address indexed to, address indexed notify, uint256 value, string foobar) +func (_IERC20 *IERC20Filterer) ParseTransfer(log types.Log) (*IERC20Transfer, error) { + event := new(IERC20Transfer) + if err := _IERC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/rolling-shutter/keyperimpl/shutterservice/help/eventtriggerbindings.go b/rolling-shutter/keyperimpl/shutterservice/help/eventtriggerbindings.go new file mode 100644 index 00000000..f9a41480 --- /dev/null +++ b/rolling-shutter/keyperimpl/shutterservice/help/eventtriggerbindings.go @@ -0,0 +1,1188 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package help + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ContextMetaData contains all meta data concerning the Context contract. +var ContextMetaData = &bind.MetaData{ + ABI: "[]", +} + +// ContextABI is the input ABI used to generate the binding from. +// Deprecated: Use ContextMetaData.ABI instead. +var ContextABI = ContextMetaData.ABI + +// Context is an auto generated Go binding around an Ethereum contract. +type Context struct { + ContextCaller // Read-only binding to the contract + ContextTransactor // Write-only binding to the contract + ContextFilterer // Log filterer for contract events +} + +// ContextCaller is an auto generated read-only Go binding around an Ethereum contract. +type ContextCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContextTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ContextTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContextFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ContextFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContextSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ContextSession struct { + Contract *Context // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContextCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ContextCallerSession struct { + Contract *ContextCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ContextTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ContextTransactorSession struct { + Contract *ContextTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContextRaw is an auto generated low-level Go binding around an Ethereum contract. +type ContextRaw struct { + Contract *Context // Generic contract binding to access the raw methods on +} + +// ContextCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ContextCallerRaw struct { + Contract *ContextCaller // Generic read-only contract binding to access the raw methods on +} + +// ContextTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ContextTransactorRaw struct { + Contract *ContextTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewContext creates a new instance of Context, bound to a specific deployed contract. +func NewContext(address common.Address, backend bind.ContractBackend) (*Context, error) { + contract, err := bindContext(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Context{ContextCaller: ContextCaller{contract: contract}, ContextTransactor: ContextTransactor{contract: contract}, ContextFilterer: ContextFilterer{contract: contract}}, nil +} + +// NewContextCaller creates a new read-only instance of Context, bound to a specific deployed contract. +func NewContextCaller(address common.Address, caller bind.ContractCaller) (*ContextCaller, error) { + contract, err := bindContext(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ContextCaller{contract: contract}, nil +} + +// NewContextTransactor creates a new write-only instance of Context, bound to a specific deployed contract. +func NewContextTransactor(address common.Address, transactor bind.ContractTransactor) (*ContextTransactor, error) { + contract, err := bindContext(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ContextTransactor{contract: contract}, nil +} + +// NewContextFilterer creates a new log filterer instance of Context, bound to a specific deployed contract. +func NewContextFilterer(address common.Address, filterer bind.ContractFilterer) (*ContextFilterer, error) { + contract, err := bindContext(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ContextFilterer{contract: contract}, nil +} + +// bindContext binds a generic wrapper to an already deployed contract. +func bindContext(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ContextMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Context *ContextRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Context.Contract.ContextCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Context *ContextRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Context.Contract.ContextTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Context *ContextRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Context.Contract.ContextTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Context *ContextCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Context.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Context *ContextTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Context.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Context *ContextTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Context.Contract.contract.Transact(opts, method, params...) +} + +// OwnableMetaData contains all meta data concerning the Ownable contract. +var OwnableMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "f2fde38b": "transferOwnership(address)", + }, +} + +// OwnableABI is the input ABI used to generate the binding from. +// Deprecated: Use OwnableMetaData.ABI instead. +var OwnableABI = OwnableMetaData.ABI + +// Deprecated: Use OwnableMetaData.Sigs instead. +// OwnableFuncSigs maps the 4-byte function signature to its string representation. +var OwnableFuncSigs = OwnableMetaData.Sigs + +// Ownable is an auto generated Go binding around an Ethereum contract. +type Ownable struct { + OwnableCaller // Read-only binding to the contract + OwnableTransactor // Write-only binding to the contract + OwnableFilterer // Log filterer for contract events +} + +// OwnableCaller is an auto generated read-only Go binding around an Ethereum contract. +type OwnableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OwnableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type OwnableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OwnableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type OwnableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OwnableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type OwnableSession struct { + Contract *Ownable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// OwnableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type OwnableCallerSession struct { + Contract *OwnableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// OwnableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type OwnableTransactorSession struct { + Contract *OwnableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// OwnableRaw is an auto generated low-level Go binding around an Ethereum contract. +type OwnableRaw struct { + Contract *Ownable // Generic contract binding to access the raw methods on +} + +// OwnableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type OwnableCallerRaw struct { + Contract *OwnableCaller // Generic read-only contract binding to access the raw methods on +} + +// OwnableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type OwnableTransactorRaw struct { + Contract *OwnableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewOwnable creates a new instance of Ownable, bound to a specific deployed contract. +func NewOwnable(address common.Address, backend bind.ContractBackend) (*Ownable, error) { + contract, err := bindOwnable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Ownable{OwnableCaller: OwnableCaller{contract: contract}, OwnableTransactor: OwnableTransactor{contract: contract}, OwnableFilterer: OwnableFilterer{contract: contract}}, nil +} + +// NewOwnableCaller creates a new read-only instance of Ownable, bound to a specific deployed contract. +func NewOwnableCaller(address common.Address, caller bind.ContractCaller) (*OwnableCaller, error) { + contract, err := bindOwnable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OwnableCaller{contract: contract}, nil +} + +// NewOwnableTransactor creates a new write-only instance of Ownable, bound to a specific deployed contract. +func NewOwnableTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnableTransactor, error) { + contract, err := bindOwnable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OwnableTransactor{contract: contract}, nil +} + +// NewOwnableFilterer creates a new log filterer instance of Ownable, bound to a specific deployed contract. +func NewOwnableFilterer(address common.Address, filterer bind.ContractFilterer) (*OwnableFilterer, error) { + contract, err := bindOwnable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OwnableFilterer{contract: contract}, nil +} + +// bindOwnable binds a generic wrapper to an already deployed contract. +func bindOwnable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OwnableMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Ownable *OwnableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Ownable.Contract.OwnableCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Ownable *OwnableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ownable.Contract.OwnableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Ownable *OwnableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Ownable.Contract.OwnableTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Ownable *OwnableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Ownable.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Ownable *OwnableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ownable.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Ownable *OwnableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Ownable.Contract.contract.Transact(opts, method, params...) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Ownable *OwnableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Ownable.contract.Call(opts, &out, "owner") + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Ownable *OwnableSession) Owner() (common.Address, error) { + return _Ownable.Contract.Owner(&_Ownable.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Ownable *OwnableCallerSession) Owner() (common.Address, error) { + return _Ownable.Contract.Owner(&_Ownable.CallOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_Ownable *OwnableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ownable.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_Ownable *OwnableSession) RenounceOwnership() (*types.Transaction, error) { + return _Ownable.Contract.RenounceOwnership(&_Ownable.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_Ownable *OwnableTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _Ownable.Contract.RenounceOwnership(&_Ownable.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Ownable *OwnableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _Ownable.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Ownable *OwnableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Ownable.Contract.TransferOwnership(&_Ownable.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Ownable *OwnableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Ownable.Contract.TransferOwnership(&_Ownable.TransactOpts, newOwner) +} + +// OwnableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Ownable contract. +type OwnableOwnershipTransferredIterator struct { + Event *OwnableOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OwnableOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OwnableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OwnableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OwnableOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OwnableOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OwnableOwnershipTransferred represents a OwnershipTransferred event raised by the Ownable contract. +type OwnableOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Ownable *OwnableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*OwnableOwnershipTransferredIterator, error) { + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Ownable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &OwnableOwnershipTransferredIterator{contract: _Ownable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Ownable *OwnableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OwnableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Ownable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OwnableOwnershipTransferred) + if err := _Ownable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Ownable *OwnableFilterer) ParseOwnershipTransferred(log types.Log) (*OwnableOwnershipTransferred, error) { + event := new(OwnableOwnershipTransferred) + if err := _Ownable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ShutterRegistryMetaData contains all meta data concerning the ShutterRegistry contract. +var ShutterRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidIdentityPrefix\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TTLTooShort\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimestampInThePast\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"eon\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"identityPrefix\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"triggerDefinition\",\"type\":\"bytes[]\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ttl\",\"type\":\"uint64\"}],\"name\":\"EventTriggerRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"eon\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"identityPrefix\",\"type\":\"bytes32\"},{\"internalType\":\"bytes[]\",\"name\":\"triggerDefinition\",\"type\":\"bytes[]\"},{\"internalType\":\"uint64\",\"name\":\"ttl\",\"type\":\"uint64\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"identity\",\"type\":\"bytes32\"}],\"name\":\"registrations\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"eon\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"ttl\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"triggerDefinitionHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "8da5cb5b": "owner()", + "205b396f": "register(uint64,bytes32,bytes[],uint64)", + "da7c6a42": "registrations(bytes32)", + "715018a6": "renounceOwnership()", + "f2fde38b": "transferOwnership(address)", + }, + Bin: "0x608060405234801561000f575f5ffd5b50335f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610081575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100789190610196565b60405180910390fd5b6100908161009660201b60201c565b506101af565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61018082610157565b9050919050565b61019081610176565b82525050565b5f6020820190506101a95f830184610187565b92915050565b610c5a806101bc5f395ff3fe608060405234801561000f575f5ffd5b5060043610610055575f3560e01c8063205b396f14610059578063715018a6146100755780638da5cb5b1461007f578063da7c6a421461009d578063f2fde38b146100cf575b5f5ffd5b610073600480360381019061006e9190610864565b6100eb565b005b61007d61036c565b005b61008761037f565b6040516100949190610923565b60405180910390f35b6100b760048036038101906100b2919061093c565b6103a6565b6040516100c693929190610985565b60405180910390f35b6100e960048036038101906100e491906109e4565b6103f2565b005b438167ffffffffffffffff16101561012f576040517f84f8e55900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f1b830361016a576040517f63a4021d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f833360405160200161017e929190610a74565b6040516020818303038152906040528051906020012090505f60015f8381526020019081526020015f2090508267ffffffffffffffff16815f0160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161061020e576040517fb5f2184000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f815f0160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161461029a5780600101548460405160200161024c9190610bba565b6040516020818303038152906040528051906020012014610299576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b82815f0160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555085815f015f6101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550836040516020016102fe9190610bba565b6040516020818303038152906040528051906020012081600101819055508567ffffffffffffffff167f7aae9d6e9dc5cd3510d70ffff8db7974a922a1c919863a85f19881e61da938308633878760405161035c9493929190610bda565b60405180910390a2505050505050565b610374610476565b61037d5f6104fd565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6001602052805f5260405f205f91509050805f015f9054906101000a900467ffffffffffffffff1690805f0160089054906101000a900467ffffffffffffffff16908060010154905083565b6103fa610476565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361046a575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016104619190610923565b60405180910390fd5b610473816104fd565b50565b61047e6105be565b73ffffffffffffffffffffffffffffffffffffffff1661049c61037f565b73ffffffffffffffffffffffffffffffffffffffff16146104fb576104bf6105be565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016104f29190610923565b60405180910390fd5b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f33905090565b5f604051905090565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff82169050919050565b6105f2816105d6565b81146105fc575f5ffd5b50565b5f8135905061060d816105e9565b92915050565b5f819050919050565b61062581610613565b811461062f575f5ffd5b50565b5f813590506106408161061c565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6106908261064a565b810181811067ffffffffffffffff821117156106af576106ae61065a565b5b80604052505050565b5f6106c16105c5565b90506106cd8282610687565b919050565b5f67ffffffffffffffff8211156106ec576106eb61065a565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff82111561071f5761071e61065a565b5b6107288261064a565b9050602081019050919050565b828183375f83830152505050565b5f61075561075084610705565b6106b8565b90508281526020810184848401111561077157610770610701565b5b61077c848285610735565b509392505050565b5f82601f83011261079857610797610646565b5b81356107a8848260208601610743565b91505092915050565b5f6107c36107be846106d2565b6106b8565b905080838252602082019050602084028301858111156107e6576107e56106fd565b5b835b8181101561082d57803567ffffffffffffffff81111561080b5761080a610646565b5b8086016108188982610784565b855260208501945050506020810190506107e8565b5050509392505050565b5f82601f83011261084b5761084a610646565b5b813561085b8482602086016107b1565b91505092915050565b5f5f5f5f6080858703121561087c5761087b6105ce565b5b5f610889878288016105ff565b945050602061089a87828801610632565b935050604085013567ffffffffffffffff8111156108bb576108ba6105d2565b5b6108c787828801610837565b92505060606108d8878288016105ff565b91505092959194509250565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61090d826108e4565b9050919050565b61091d81610903565b82525050565b5f6020820190506109365f830184610914565b92915050565b5f60208284031215610951576109506105ce565b5b5f61095e84828501610632565b91505092915050565b610970816105d6565b82525050565b61097f81610613565b82525050565b5f6060820190506109985f830186610967565b6109a56020830185610967565b6109b26040830184610976565b949350505050565b6109c381610903565b81146109cd575f5ffd5b50565b5f813590506109de816109ba565b92915050565b5f602082840312156109f9576109f86105ce565b5b5f610a06848285016109d0565b91505092915050565b5f819050919050565b610a29610a2482610613565b610a0f565b82525050565b5f8160601b9050919050565b5f610a4582610a2f565b9050919050565b5f610a5682610a3b565b9050919050565b610a6e610a6982610903565b610a4c565b82525050565b5f610a7f8285610a18565b602082019150610a8f8284610a5d565b6014820191508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f610afa82610ac8565b610b048185610ad2565b9350610b14818560208601610ae2565b610b1d8161064a565b840191505092915050565b5f610b338383610af0565b905092915050565b5f602082019050919050565b5f610b5182610a9f565b610b5b8185610aa9565b935083602082028501610b6d85610ab9565b805f5b85811015610ba85784840389528151610b898582610b28565b9450610b9483610b3b565b925060208a01995050600181019050610b70565b50829750879550505050505092915050565b5f6020820190508181035f830152610bd28184610b47565b905092915050565b5f608082019050610bed5f830187610976565b610bfa6020830186610914565b8181036040830152610c0c8185610b47565b9050610c1b6060830184610967565b9594505050505056fea26469706673582212209ad31602fbb4bc228e7ee36774a68a11d1c3d06a60fa340db05278e6658e25bc64736f6c634300081c0033", +} + +// ShutterRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use ShutterRegistryMetaData.ABI instead. +var ShutterRegistryABI = ShutterRegistryMetaData.ABI + +// Deprecated: Use ShutterRegistryMetaData.Sigs instead. +// ShutterRegistryFuncSigs maps the 4-byte function signature to its string representation. +var ShutterRegistryFuncSigs = ShutterRegistryMetaData.Sigs + +// ShutterRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ShutterRegistryMetaData.Bin instead. +var ShutterRegistryBin = ShutterRegistryMetaData.Bin + +// DeployShutterRegistry deploys a new Ethereum contract, binding an instance of ShutterRegistry to it. +func DeployShutterRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ShutterRegistry, error) { + parsed, err := ShutterRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ShutterRegistryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ShutterRegistry{ShutterRegistryCaller: ShutterRegistryCaller{contract: contract}, ShutterRegistryTransactor: ShutterRegistryTransactor{contract: contract}, ShutterRegistryFilterer: ShutterRegistryFilterer{contract: contract}}, nil +} + +// ShutterRegistry is an auto generated Go binding around an Ethereum contract. +type ShutterRegistry struct { + ShutterRegistryCaller // Read-only binding to the contract + ShutterRegistryTransactor // Write-only binding to the contract + ShutterRegistryFilterer // Log filterer for contract events +} + +// ShutterRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type ShutterRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ShutterRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ShutterRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ShutterRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ShutterRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ShutterRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ShutterRegistrySession struct { + Contract *ShutterRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ShutterRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ShutterRegistryCallerSession struct { + Contract *ShutterRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ShutterRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ShutterRegistryTransactorSession struct { + Contract *ShutterRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ShutterRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type ShutterRegistryRaw struct { + Contract *ShutterRegistry // Generic contract binding to access the raw methods on +} + +// ShutterRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ShutterRegistryCallerRaw struct { + Contract *ShutterRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// ShutterRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ShutterRegistryTransactorRaw struct { + Contract *ShutterRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewShutterRegistry creates a new instance of ShutterRegistry, bound to a specific deployed contract. +func NewShutterRegistry(address common.Address, backend bind.ContractBackend) (*ShutterRegistry, error) { + contract, err := bindShutterRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ShutterRegistry{ShutterRegistryCaller: ShutterRegistryCaller{contract: contract}, ShutterRegistryTransactor: ShutterRegistryTransactor{contract: contract}, ShutterRegistryFilterer: ShutterRegistryFilterer{contract: contract}}, nil +} + +// NewShutterRegistryCaller creates a new read-only instance of ShutterRegistry, bound to a specific deployed contract. +func NewShutterRegistryCaller(address common.Address, caller bind.ContractCaller) (*ShutterRegistryCaller, error) { + contract, err := bindShutterRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ShutterRegistryCaller{contract: contract}, nil +} + +// NewShutterRegistryTransactor creates a new write-only instance of ShutterRegistry, bound to a specific deployed contract. +func NewShutterRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*ShutterRegistryTransactor, error) { + contract, err := bindShutterRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ShutterRegistryTransactor{contract: contract}, nil +} + +// NewShutterRegistryFilterer creates a new log filterer instance of ShutterRegistry, bound to a specific deployed contract. +func NewShutterRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*ShutterRegistryFilterer, error) { + contract, err := bindShutterRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ShutterRegistryFilterer{contract: contract}, nil +} + +// bindShutterRegistry binds a generic wrapper to an already deployed contract. +func bindShutterRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ShutterRegistryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ShutterRegistry *ShutterRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ShutterRegistry.Contract.ShutterRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ShutterRegistry *ShutterRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ShutterRegistry.Contract.ShutterRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ShutterRegistry *ShutterRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ShutterRegistry.Contract.ShutterRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ShutterRegistry *ShutterRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ShutterRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ShutterRegistry *ShutterRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ShutterRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ShutterRegistry *ShutterRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ShutterRegistry.Contract.contract.Transact(opts, method, params...) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ShutterRegistry *ShutterRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ShutterRegistry.contract.Call(opts, &out, "owner") + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ShutterRegistry *ShutterRegistrySession) Owner() (common.Address, error) { + return _ShutterRegistry.Contract.Owner(&_ShutterRegistry.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ShutterRegistry *ShutterRegistryCallerSession) Owner() (common.Address, error) { + return _ShutterRegistry.Contract.Owner(&_ShutterRegistry.CallOpts) +} + +// Registrations is a free data retrieval call binding the contract method 0xda7c6a42. +// +// Solidity: function registrations(bytes32 identity) view returns(uint64 eon, uint64 ttl, bytes32 triggerDefinitionHash) +func (_ShutterRegistry *ShutterRegistryCaller) Registrations(opts *bind.CallOpts, identity [32]byte) (struct { + Eon uint64 + Ttl uint64 + TriggerDefinitionHash [32]byte +}, error, +) { + var out []interface{} + err := _ShutterRegistry.contract.Call(opts, &out, "registrations", identity) + + outstruct := new(struct { + Eon uint64 + Ttl uint64 + TriggerDefinitionHash [32]byte + }) + if err != nil { + return *outstruct, err + } + + outstruct.Eon = *abi.ConvertType(out[0], new(uint64)).(*uint64) + outstruct.Ttl = *abi.ConvertType(out[1], new(uint64)).(*uint64) + outstruct.TriggerDefinitionHash = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err +} + +// Registrations is a free data retrieval call binding the contract method 0xda7c6a42. +// +// Solidity: function registrations(bytes32 identity) view returns(uint64 eon, uint64 ttl, bytes32 triggerDefinitionHash) +func (_ShutterRegistry *ShutterRegistrySession) Registrations(identity [32]byte) (struct { + Eon uint64 + Ttl uint64 + TriggerDefinitionHash [32]byte +}, error, +) { + return _ShutterRegistry.Contract.Registrations(&_ShutterRegistry.CallOpts, identity) +} + +// Registrations is a free data retrieval call binding the contract method 0xda7c6a42. +// +// Solidity: function registrations(bytes32 identity) view returns(uint64 eon, uint64 ttl, bytes32 triggerDefinitionHash) +func (_ShutterRegistry *ShutterRegistryCallerSession) Registrations(identity [32]byte) (struct { + Eon uint64 + Ttl uint64 + TriggerDefinitionHash [32]byte +}, error, +) { + return _ShutterRegistry.Contract.Registrations(&_ShutterRegistry.CallOpts, identity) +} + +// Register is a paid mutator transaction binding the contract method 0x205b396f. +// +// Solidity: function register(uint64 eon, bytes32 identityPrefix, bytes[] triggerDefinition, uint64 ttl) returns() +func (_ShutterRegistry *ShutterRegistryTransactor) Register(opts *bind.TransactOpts, eon uint64, identityPrefix [32]byte, triggerDefinition [][]byte, ttl uint64) (*types.Transaction, error) { + return _ShutterRegistry.contract.Transact(opts, "register", eon, identityPrefix, triggerDefinition, ttl) +} + +// Register is a paid mutator transaction binding the contract method 0x205b396f. +// +// Solidity: function register(uint64 eon, bytes32 identityPrefix, bytes[] triggerDefinition, uint64 ttl) returns() +func (_ShutterRegistry *ShutterRegistrySession) Register(eon uint64, identityPrefix [32]byte, triggerDefinition [][]byte, ttl uint64) (*types.Transaction, error) { + return _ShutterRegistry.Contract.Register(&_ShutterRegistry.TransactOpts, eon, identityPrefix, triggerDefinition, ttl) +} + +// Register is a paid mutator transaction binding the contract method 0x205b396f. +// +// Solidity: function register(uint64 eon, bytes32 identityPrefix, bytes[] triggerDefinition, uint64 ttl) returns() +func (_ShutterRegistry *ShutterRegistryTransactorSession) Register(eon uint64, identityPrefix [32]byte, triggerDefinition [][]byte, ttl uint64) (*types.Transaction, error) { + return _ShutterRegistry.Contract.Register(&_ShutterRegistry.TransactOpts, eon, identityPrefix, triggerDefinition, ttl) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ShutterRegistry *ShutterRegistryTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ShutterRegistry.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ShutterRegistry *ShutterRegistrySession) RenounceOwnership() (*types.Transaction, error) { + return _ShutterRegistry.Contract.RenounceOwnership(&_ShutterRegistry.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ShutterRegistry *ShutterRegistryTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ShutterRegistry.Contract.RenounceOwnership(&_ShutterRegistry.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ShutterRegistry *ShutterRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ShutterRegistry.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ShutterRegistry *ShutterRegistrySession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ShutterRegistry.Contract.TransferOwnership(&_ShutterRegistry.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ShutterRegistry *ShutterRegistryTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ShutterRegistry.Contract.TransferOwnership(&_ShutterRegistry.TransactOpts, newOwner) +} + +// ShutterRegistryEventTriggerRegisteredIterator is returned from FilterEventTriggerRegistered and is used to iterate over the raw logs and unpacked data for EventTriggerRegistered events raised by the ShutterRegistry contract. +type ShutterRegistryEventTriggerRegisteredIterator struct { + Event *ShutterRegistryEventTriggerRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ShutterRegistryEventTriggerRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ShutterRegistryEventTriggerRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ShutterRegistryEventTriggerRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ShutterRegistryEventTriggerRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ShutterRegistryEventTriggerRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ShutterRegistryEventTriggerRegistered represents a EventTriggerRegistered event raised by the ShutterRegistry contract. +type ShutterRegistryEventTriggerRegistered struct { + Eon uint64 + IdentityPrefix [32]byte + Sender common.Address + TriggerDefinition [][]byte + Ttl uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEventTriggerRegistered is a free log retrieval operation binding the contract event 0x7aae9d6e9dc5cd3510d70ffff8db7974a922a1c919863a85f19881e61da93830. +// +// Solidity: event EventTriggerRegistered(uint64 indexed eon, bytes32 identityPrefix, address sender, bytes[] triggerDefinition, uint64 ttl) +func (_ShutterRegistry *ShutterRegistryFilterer) FilterEventTriggerRegistered(opts *bind.FilterOpts, eon []uint64) (*ShutterRegistryEventTriggerRegisteredIterator, error) { + var eonRule []interface{} + for _, eonItem := range eon { + eonRule = append(eonRule, eonItem) + } + + logs, sub, err := _ShutterRegistry.contract.FilterLogs(opts, "EventTriggerRegistered", eonRule) + if err != nil { + return nil, err + } + return &ShutterRegistryEventTriggerRegisteredIterator{contract: _ShutterRegistry.contract, event: "EventTriggerRegistered", logs: logs, sub: sub}, nil +} + +// WatchEventTriggerRegistered is a free log subscription operation binding the contract event 0x7aae9d6e9dc5cd3510d70ffff8db7974a922a1c919863a85f19881e61da93830. +// +// Solidity: event EventTriggerRegistered(uint64 indexed eon, bytes32 identityPrefix, address sender, bytes[] triggerDefinition, uint64 ttl) +func (_ShutterRegistry *ShutterRegistryFilterer) WatchEventTriggerRegistered(opts *bind.WatchOpts, sink chan<- *ShutterRegistryEventTriggerRegistered, eon []uint64) (event.Subscription, error) { + var eonRule []interface{} + for _, eonItem := range eon { + eonRule = append(eonRule, eonItem) + } + + logs, sub, err := _ShutterRegistry.contract.WatchLogs(opts, "EventTriggerRegistered", eonRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ShutterRegistryEventTriggerRegistered) + if err := _ShutterRegistry.contract.UnpackLog(event, "EventTriggerRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseEventTriggerRegistered is a log parse operation binding the contract event 0x7aae9d6e9dc5cd3510d70ffff8db7974a922a1c919863a85f19881e61da93830. +// +// Solidity: event EventTriggerRegistered(uint64 indexed eon, bytes32 identityPrefix, address sender, bytes[] triggerDefinition, uint64 ttl) +func (_ShutterRegistry *ShutterRegistryFilterer) ParseEventTriggerRegistered(log types.Log) (*ShutterRegistryEventTriggerRegistered, error) { + event := new(ShutterRegistryEventTriggerRegistered) + if err := _ShutterRegistry.contract.UnpackLog(event, "EventTriggerRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ShutterRegistryOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ShutterRegistry contract. +type ShutterRegistryOwnershipTransferredIterator struct { + Event *ShutterRegistryOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ShutterRegistryOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ShutterRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ShutterRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ShutterRegistryOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ShutterRegistryOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ShutterRegistryOwnershipTransferred represents a OwnershipTransferred event raised by the ShutterRegistry contract. +type ShutterRegistryOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ShutterRegistry *ShutterRegistryFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ShutterRegistryOwnershipTransferredIterator, error) { + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ShutterRegistry.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ShutterRegistryOwnershipTransferredIterator{contract: _ShutterRegistry.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ShutterRegistry *ShutterRegistryFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ShutterRegistryOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ShutterRegistry.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ShutterRegistryOwnershipTransferred) + if err := _ShutterRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ShutterRegistry *ShutterRegistryFilterer) ParseOwnershipTransferred(log types.Log) (*ShutterRegistryOwnershipTransferred, error) { + event := new(ShutterRegistryOwnershipTransferred) + if err := _ShutterRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/rolling-shutter/keyperimpl/shutterservice/keyper.go b/rolling-shutter/keyperimpl/shutterservice/keyper.go index 137febc1..aa171ddd 100644 --- a/rolling-shutter/keyperimpl/shutterservice/keyper.go +++ b/rolling-shutter/keyperimpl/shutterservice/keyper.go @@ -10,13 +10,13 @@ import ( "github.com/jackc/pgx/v4/pgxpool" "github.com/pkg/errors" "github.com/rs/zerolog/log" - registryBindings "github.com/shutter-network/contracts/v2/bindings/shutterregistry" "github.com/shutter-network/rolling-shutter/rolling-shutter/eonkeypublisher" "github.com/shutter-network/rolling-shutter/rolling-shutter/keyper" "github.com/shutter-network/rolling-shutter/rolling-shutter/keyper/epochkghandler" "github.com/shutter-network/rolling-shutter/rolling-shutter/keyper/kprconfig" "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/shutterservice/database" + registryBindings "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/shutterservice/help" "github.com/shutter-network/rolling-shutter/rolling-shutter/medley/broker" "github.com/shutter-network/rolling-shutter/rolling-shutter/medley/chainsync" syncevent "github.com/shutter-network/rolling-shutter/rolling-shutter/medley/chainsync/event" @@ -156,7 +156,7 @@ func (kpr *Keyper) initRegistrySyncer(ctx context.Context) error { Str("contract-address", kpr.config.Chain.Contracts.KeyperSetManager.Hex()). Msg("initializing registry syncer") - contract, err := registryBindings.NewShutterregistry(kpr.config.Chain.Contracts.ShutterRegistry, client) + contract, err := registryBindings.NewShutterRegistry(kpr.config.Chain.Contracts.ShutterRegistry, client) if err != nil { return err } diff --git a/rolling-shutter/keyperimpl/shutterservice/newblock.go b/rolling-shutter/keyperimpl/shutterservice/newblock.go index 3496a566..56fd4115 100644 --- a/rolling-shutter/keyperimpl/shutterservice/newblock.go +++ b/rolling-shutter/keyperimpl/shutterservice/newblock.go @@ -25,11 +25,31 @@ func (kpr *Keyper) processNewBlock(ctx context.Context, ev *syncevent.LatestBloc return err } } + // check all our installed filters + err := kpr.maybeTriggerEventBased(ctx, ev) + if err != nil { + return err + } return kpr.maybeTriggerDecryption(ctx, ev) } +// maybeTriggerEventBased(ctx context.Context, block *syncevent.LatestBlock) error +// will check installed filters for registered events + +func (kpr *Keyper) maybeTriggerEventBased(ctx context.Context, block *syncevent.LatestBlock) error { + // we should have a bloom filter for each registered and not resolved trigger + // check block headers logs bloom + // if match, check exact conditions: + // - contract address + // - event signature + // - specific conditions + // if match: trigger decryption + // mark in db as resolved + return errors.Errorf("not implemented") +} + // maybeTriggerDecryption triggers decryption for the identities registered if -// - it hasn't been triggered for thos identities before and +// - it hasn't been triggered for those identities before and // - the keyper is part of the corresponding keyper set. func (kpr *Keyper) maybeTriggerDecryption(ctx context.Context, block *syncevent.LatestBlock) error { if kpr.latestTriggeredTime != nil && block.Header.Time <= *kpr.latestTriggeredTime { diff --git a/rolling-shutter/keyperimpl/shutterservice/newblock_test.go b/rolling-shutter/keyperimpl/shutterservice/newblock_test.go index 973071d6..379652d7 100644 --- a/rolling-shutter/keyperimpl/shutterservice/newblock_test.go +++ b/rolling-shutter/keyperimpl/shutterservice/newblock_test.go @@ -8,13 +8,13 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/shutter-network/contracts/v2/bindings/shutterregistry" "gotest.tools/assert" obskeyper "github.com/shutter-network/rolling-shutter/rolling-shutter/chainobserver/db/keyper" corekeyperdatabase "github.com/shutter-network/rolling-shutter/rolling-shutter/keyper/database" "github.com/shutter-network/rolling-shutter/rolling-shutter/keyper/epochkghandler" servicedatabase "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/shutterservice/database" + shutterregistry "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/shutterservice/help" "github.com/shutter-network/rolling-shutter/rolling-shutter/medley/broker" "github.com/shutter-network/rolling-shutter/rolling-shutter/medley/chainsync/event" "github.com/shutter-network/rolling-shutter/rolling-shutter/medley/configuration" @@ -62,7 +62,7 @@ func TestProcessBlockSuccess(t *testing.T) { activationBlockNumber := 100 identityPrefix, _ := generateRandom32Bytes() - identity := computeIdentity(&shutterregistry.ShutterregistryIdentityRegistered{ + identity := computeIdentity(&shutterregistry.ShutterRegistryEventTriggerRegistered{ IdentityPrefix: [32]byte(identityPrefix), Sender: sender, }) diff --git a/rolling-shutter/keyperimpl/shutterservice/registrysyncer.go b/rolling-shutter/keyperimpl/shutterservice/registrysyncer.go index 52e21142..2c52f763 100644 --- a/rolling-shutter/keyperimpl/shutterservice/registrysyncer.go +++ b/rolling-shutter/keyperimpl/shutterservice/registrysyncer.go @@ -14,9 +14,9 @@ import ( "github.com/jackc/pgx/v4/pgxpool" "github.com/pkg/errors" "github.com/rs/zerolog/log" - registryBindings "github.com/shutter-network/contracts/v2/bindings/shutterregistry" "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/shutterservice/database" + registryBindings "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/shutterservice/help" "github.com/shutter-network/rolling-shutter/rolling-shutter/medley" "github.com/shutter-network/rolling-shutter/rolling-shutter/shdb" ) @@ -27,7 +27,7 @@ const ( ) type RegistrySyncer struct { - Contract *registryBindings.Shutterregistry + Contract *registryBindings.ShutterRegistry DBPool *pgxpool.Pool ExecutionClient *ethclient.Client SyncStartBlockNumber uint64 @@ -164,7 +164,7 @@ func (s *RegistrySyncer) syncRange( return errors.Wrap(err, "failed to get execution block header by number") } err = s.DBPool.BeginFunc(ctx, func(tx pgx.Tx) error { - err = s.insertIdentityRegisteredEvents(ctx, tx, filteredEvents) + err = s.insertEventTriggerRegisteredEvents(ctx, tx, filteredEvents) if err != nil { return err } @@ -191,17 +191,17 @@ func (s *RegistrySyncer) fetchEvents( ctx context.Context, start, end uint64, -) ([]*registryBindings.ShutterregistryIdentityRegistered, error) { +) ([]*registryBindings.ShutterRegistryEventTriggerRegistered, error) { opts := bind.FilterOpts{ Start: start, End: &end, Context: ctx, } - it, err := s.Contract.ShutterregistryFilterer.FilterIdentityRegistered(&opts) + it, err := s.Contract.ShutterRegistryFilterer.FilterEventTriggerRegistered(&opts, nil) if err != nil { return nil, errors.Wrap(err, "failed to query identity registered events") } - events := []*registryBindings.ShutterregistryIdentityRegistered{} + events := []*registryBindings.ShutterRegistryEventTriggerRegistered{} for it.Next() { events = append(events, it.Event) } @@ -212,9 +212,9 @@ func (s *RegistrySyncer) fetchEvents( } func (s *RegistrySyncer) filterEvents( - events []*registryBindings.ShutterregistryIdentityRegistered, -) []*registryBindings.ShutterregistryIdentityRegistered { - filteredEvents := []*registryBindings.ShutterregistryIdentityRegistered{} + events []*registryBindings.ShutterRegistryEventTriggerRegistered, +) []*registryBindings.ShutterRegistryEventTriggerRegistered { + filteredEvents := []*registryBindings.ShutterRegistryEventTriggerRegistered{} for _, event := range events { if event.Eon > math.MaxInt64 { log.Debug(). @@ -232,15 +232,24 @@ func (s *RegistrySyncer) filterEvents( } // insertIdentityRegisteredEvents inserts the given events into the database. -func (s *RegistrySyncer) insertIdentityRegisteredEvents( +func (s *RegistrySyncer) insertEventTriggerRegisteredEvents( ctx context.Context, tx pgx.Tx, - events []*registryBindings.ShutterregistryIdentityRegistered, + events []*registryBindings.ShutterRegistryEventTriggerRegistered, ) error { queries := database.New(tx) for _, event := range events { identity := computeIdentity(event) - _, err := queries.InsertIdentityRegisteredEvent(ctx, database.InsertIdentityRegisteredEventParams{ + var def []byte + for i := range event.TriggerDefinition { + def = append(def, event.TriggerDefinition[i]...) + } + parsed := EventTriggerDefinition{} + err := parsed.UnmarshalBytes(event.TriggerDefinition) + if err != nil { + return errors.Wrap(err, "could not parse event definition from event") + } + _, err = queries.InsertEventTriggerRegisteredEvent(ctx, database.InsertEventTriggerRegisteredEventParams{ BlockNumber: int64(event.Raw.BlockNumber), BlockHash: event.Raw.BlockHash[:], TxIndex: int64(event.Raw.TxIndex), @@ -248,7 +257,8 @@ func (s *RegistrySyncer) insertIdentityRegisteredEvents( Eon: int64(event.Eon), IdentityPrefix: event.IdentityPrefix[:], Sender: shdb.EncodeAddress(event.Sender), - Timestamp: int64(event.Timestamp), + Definition: def[:], + Ttl: int64(event.Ttl), Identity: identity, }) if err != nil { @@ -259,13 +269,13 @@ func (s *RegistrySyncer) insertIdentityRegisteredEvents( Uint64("eon", event.Eon). Hex("identityPrefix", event.IdentityPrefix[:]). Hex("sender", event.Sender.Bytes()). - Uint64("timestamp", event.Timestamp). - Msg("synced new identity registered event") + Uint64("ttl", event.Ttl). + Msg("synced new event trigger registered event") } return nil } -func computeIdentity(event *registryBindings.ShutterregistryIdentityRegistered) []byte { +func computeIdentity(event *registryBindings.ShutterRegistryEventTriggerRegistered) []byte { // TODO: may need to change this if we want to create identity other way var buf bytes.Buffer buf.Write(event.IdentityPrefix[:]) diff --git a/rolling-shutter/keyperimpl/shutterservice/registrysyncer_test.go b/rolling-shutter/keyperimpl/shutterservice/registrysyncer_test.go index 7c3a9dae..f8e8057a 100644 --- a/rolling-shutter/keyperimpl/shutterservice/registrysyncer_test.go +++ b/rolling-shutter/keyperimpl/shutterservice/registrysyncer_test.go @@ -4,34 +4,37 @@ import ( "context" "crypto/ecdsa" cryptoRand "crypto/rand" + "math" + "math/rand/v2" "testing" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/jackc/pgx/v4" - registryBindings "github.com/shutter-network/contracts/v2/bindings/shutterregistry" "gotest.tools/assert" "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/shutterservice/database" + registryBindings "github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/shutterservice/help" "github.com/shutter-network/rolling-shutter/rolling-shutter/medley/testsetup" ) -func TestFilterIdentityRegisteredEvents(t *testing.T) { +func TestFilterEventTriggerRegisteredEvents(t *testing.T) { if testing.Short() { t.Skip("skipping integration test") } - events := make([]*registryBindings.ShutterregistryIdentityRegistered, 2) + events := make([]*registryBindings.ShutterRegistryEventTriggerRegistered, 2) for i := 0; i < 2; i++ { identityPrefix, err := generateRandom32Bytes() assert.NilError(t, err) _, sender, err := generateRandomAccount() assert.NilError(t, err) - events[i] = ®istryBindings.ShutterregistryIdentityRegistered{ - Eon: uint64(i), - IdentityPrefix: [32]byte(identityPrefix), - Sender: sender, - Timestamp: uint64(time.Now().Unix()), + def, err := generateRandomEventTriggerDefinition() + events[i] = ®istryBindings.ShutterRegistryEventTriggerRegistered{ + Eon: uint64(i), + IdentityPrefix: [32]byte(identityPrefix), + Sender: sender, + TriggerDefinition: def.MarshalBytes(), + Ttl: rand.Uint64(), } } @@ -41,23 +44,26 @@ func TestFilterIdentityRegisteredEvents(t *testing.T) { assert.DeepEqual(t, finalEvents, events) } -func TestInsertIdentityRegisteredEvents(t *testing.T) { +func TestInsertEventTriggerRegisteredEvents(t *testing.T) { if testing.Short() { t.Skip("skipping integration test") } ctx := context.Background() - events := make([]*registryBindings.ShutterregistryIdentityRegistered, 2) + events := make([]*registryBindings.ShutterRegistryEventTriggerRegistered, 2) for i := 0; i < 2; i++ { identityPrefix, err := generateRandom32Bytes() assert.NilError(t, err) _, sender, err := generateRandomAccount() assert.NilError(t, err) - events[i] = ®istryBindings.ShutterregistryIdentityRegistered{ - Eon: uint64(i), - IdentityPrefix: [32]byte(identityPrefix), - Sender: sender, - Timestamp: uint64(time.Now().Unix()), + def, err := generateRandomEventTriggerDefinition() + assert.NilError(t, err) + events[i] = ®istryBindings.ShutterRegistryEventTriggerRegistered{ + Eon: uint64(i), + IdentityPrefix: [32]byte(identityPrefix), + Sender: sender, + TriggerDefinition: def.MarshalBytes(), + Ttl: rand.Uint64() % math.MaxInt64, } } @@ -67,12 +73,44 @@ func TestInsertIdentityRegisteredEvents(t *testing.T) { rs := RegistrySyncer{} err := dbpool.BeginFunc(ctx, func(tx pgx.Tx) error { - err := rs.insertIdentityRegisteredEvents(ctx, tx, events) + err := rs.insertEventTriggerRegisteredEvents(ctx, tx, events) return err }) assert.NilError(t, err) } +func generateRandomEventTriggerDefinition() (*EventTriggerDefinition, error) { + _, randomContract, err := generateRandomAccount() + if err != nil { + return nil, err + } + randomTopic, err := generateRandom32Bytes() + if err != nil { + return nil, err + } + randomSig, err := generateRandom32Bytes() + if err != nil { + return nil, err + } + def := EventTriggerDefinition{ + Contract: randomContract, + Signature: EvtSignature{ + hashed: (*common.Hash)(randomSig), + }, + Conditions: []Condition{ + { + Constraint: MatchConstraint{ + target: randomTopic, + }, + Location: TopicData{ + number: 1, + }, + }, + }, + } + return &def, nil +} + func generateRandom32Bytes() ([]byte, error) { b := make([]byte, 32) _, err := cryptoRand.Read(b)