Commit c25ac1d7 authored by 袁兴强's avatar 袁兴强

gowasm init

parent 0be50d74
...@@ -28,6 +28,7 @@ require ( ...@@ -28,6 +28,7 @@ require (
github.com/miguelmota/go-solidity-sha3 v0.1.0 github.com/miguelmota/go-solidity-sha3 v0.1.0
github.com/mr-tron/base58 v1.1.3 github.com/mr-tron/base58 v1.1.3
github.com/pborman/uuid v1.2.0 github.com/pborman/uuid v1.2.0
github.com/perlin-network/life v0.0.0-20191203030451-05c0e0f7eaea
github.com/phoreproject/bls v0.0.0-20200525203911-a88a5ae26844 github.com/phoreproject/bls v0.0.0-20200525203911-a88a5ae26844
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v0.9.2 // indirect github.com/prometheus/client_golang v0.9.2 // indirect
......
...@@ -125,6 +125,8 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4 ...@@ -125,6 +125,8 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c h1:JHHhtb9XWJrGNMcrVP6vyzO4dusgi/HnceHTgxSejUM= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c h1:JHHhtb9XWJrGNMcrVP6vyzO4dusgi/HnceHTgxSejUM=
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa h1:XKAhUk/dtp+CV0VO6mhG2V7jA9vbcGcnYF/Ay9NjZrY= github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa h1:XKAhUk/dtp+CV0VO6mhG2V7jA9vbcGcnYF/Ay9NjZrY=
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
...@@ -147,6 +149,8 @@ github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x ...@@ -147,6 +149,8 @@ github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x
github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA=
github.com/go-interpreter/wagon v0.6.0 h1:BBxDxjiJiHgw9EdkYXAWs8NHhwnazZ5P2EWBW5hFNWw=
github.com/go-interpreter/wagon v0.6.0/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5dFdO1hAueZLc=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM=
...@@ -541,6 +545,8 @@ github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= ...@@ -541,6 +545,8 @@ github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/perlin-network/life v0.0.0-20191203030451-05c0e0f7eaea h1:okKoivlkNRRLqXraEtatHfEhW+D71QTwkaj+4n4M2Xc=
github.com/perlin-network/life v0.0.0-20191203030451-05c0e0f7eaea/go.mod h1:3KEU5Dm8MAYWZqity880wOFJ9PhQjyKVZGwAEfc5Q4E=
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
github.com/phoreproject/bls v0.0.0-20200525203911-a88a5ae26844 h1:Yflyn+XFLEu7RPzxovgEVLP6Es8JLJrHqdXunpm2ak4= github.com/phoreproject/bls v0.0.0-20200525203911-a88a5ae26844 h1:Yflyn+XFLEu7RPzxovgEVLP6Es8JLJrHqdXunpm2ak4=
github.com/phoreproject/bls v0.0.0-20200525203911-a88a5ae26844/go.mod h1:xHJKf2TLXUA39Dhv8k5QmQOxLsbrb1KeTS/3ERfLeqc= github.com/phoreproject/bls v0.0.0-20200525203911-a88a5ae26844/go.mod h1:xHJKf2TLXUA39Dhv8k5QmQOxLsbrb1KeTS/3ERfLeqc=
...@@ -633,6 +639,8 @@ github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJ ...@@ -633,6 +639,8 @@ github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJ
github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/tjfoc/gmsm v1.3.1 h1:+k3IAlF81c31/TllJmIfuCYnjl8ziMdTWGWJcP9J1uo= github.com/tjfoc/gmsm v1.3.1 h1:+k3IAlF81c31/TllJmIfuCYnjl8ziMdTWGWJcP9J1uo=
github.com/tjfoc/gmsm v1.3.1/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= github.com/tjfoc/gmsm v1.3.1/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/twitchyliquid64/golang-asm v0.0.0-20190126203739-365674df15fc h1:RTUQlKzoZZVG3umWNzOYeFecQLIh+dbxXvJp1zPQJTI=
github.com/twitchyliquid64/golang-asm v0.0.0-20190126203739-365674df15fc/go.mod h1:NoCfSFWosfqMqmmD7hApkirIK9ozpHjxRnRxs1l413A=
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4=
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
...@@ -646,6 +654,8 @@ github.com/valyala/fasthttp v1.5.0 h1:dhq+O9pmNZFF6qAXpasMO1xSm7dL4qEz2ylfZN8BG9 ...@@ -646,6 +654,8 @@ github.com/valyala/fasthttp v1.5.0 h1:dhq+O9pmNZFF6qAXpasMO1xSm7dL4qEz2ylfZN8BG9
github.com/valyala/fasthttp v1.5.0/go.mod h1:eriCz9OhZjKCGfJ185a/IDgNl0bg9IbzfpcslMZXU1c= github.com/valyala/fasthttp v1.5.0/go.mod h1:eriCz9OhZjKCGfJ185a/IDgNl0bg9IbzfpcslMZXU1c=
github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4=
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=
...@@ -749,6 +759,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h ...@@ -749,6 +759,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190306220234-b354f8bf4d9e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
...@@ -794,6 +805,7 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IV ...@@ -794,6 +805,7 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IV
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
......
...@@ -30,5 +30,6 @@ import ( ...@@ -30,5 +30,6 @@ import (
_ "github.com/33cn/plugin/plugin/dapp/trade" //auto gen _ "github.com/33cn/plugin/plugin/dapp/trade" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/unfreeze" //auto gen _ "github.com/33cn/plugin/plugin/dapp/unfreeze" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/valnode" //auto gen _ "github.com/33cn/plugin/plugin/dapp/valnode" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/wasm" //auto gen
_ "github.com/33cn/plugin/plugin/dapp/x2ethereum" //auto gen _ "github.com/33cn/plugin/plugin/dapp/x2ethereum" //auto gen
) )
package commands
import (
"fmt"
"io/ioutil"
"os"
"github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
wasmtypes "github.com/33cn/plugin/plugin/dapp/wasm/types"
"github.com/spf13/cobra"
)
// TokenCmd token 命令行
func Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "wasm",
Short: "Wasm management",
Args: cobra.MinimumNArgs(1),
}
cmd.AddCommand(
CmdCheckContract(),
CmdCreateContract(),
CmdCallContract(),
)
return cmd
}
func CmdCheckContract() *cobra.Command {
cmd := &cobra.Command{
Use: "check",
Short: "Check whether the contract with the given name exists or not.",
Run: checkContract,
}
cmd.Flags().StringP("name", "n", "", "contract name")
_ = cmd.MarkFlagRequired("name")
return cmd
}
func CmdCreateContract() *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "publish a new contract on chain33",
Run: createContract,
}
cmd.Flags().StringP("name", "n", "", "contract name")
cmd.Flags().StringP("path", "p", "", "path of the wasm file, such as ./test.wasm")
_ = cmd.MarkFlagRequired("name")
_ = cmd.MarkFlagRequired("path")
return cmd
}
func CmdCallContract() *cobra.Command {
cmd := &cobra.Command{
Use: "call",
Short: "call contract on chain33",
Run: callContract,
}
cmd.Flags().StringP("name", "n", "", "contract name")
cmd.Flags().StringP("method", "m", "", "method name")
cmd.Flags().IntSliceP("parameters", "p", nil, "parameters of the method which should be num")
_ = cmd.MarkFlagRequired("name")
_ = cmd.MarkFlagRequired("method")
return cmd
}
func checkContract(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
name, _ := cmd.Flags().GetString("name")
params := rpctypes.Query4Jrpc{
Execer: wasmtypes.WasmX,
FuncName: "Check",
Payload: types.MustPBToJSON(&wasmtypes.QueryCheckConract{
Name: name,
}),
}
var resp types.Reply
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &resp)
ctx.Run()
}
func createContract(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
name, _ := cmd.Flags().GetString("name")
path, _ := cmd.Flags().GetString("path")
// Read WebAssembly *.wasm file.
code, err := ioutil.ReadFile(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
payload := wasmtypes.WasmCreate{
Name: name,
Code: code,
}
params := rpctypes.CreateTxIn{
Execer: wasmtypes.WasmX,
ActionName: "Create",
Payload: types.MustPBToJSON(&payload),
}
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
func callContract(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
name, _ := cmd.Flags().GetString("name")
method, _ := cmd.Flags().GetString("method")
parameters, _ := cmd.Flags().GetIntSlice("parameters")
var parameters2 []int64
for _, param := range parameters {
parameters2 = append(parameters2, int64(param))
}
payload := wasmtypes.WasmCall{
Contract: name,
Method: method,
Parameters: parameters2,
}
params := rpctypes.CreateTxIn{
Execer: wasmtypes.WasmX,
ActionName: "Call",
Payload: types.MustPBToJSON(&payload),
}
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
package executor
import (
"github.com/33cn/chain33/types"
types2 "github.com/33cn/plugin/plugin/dapp/wasm/types"
)
func setStateDB(key, value []byte) {
wasmCB.kvs = append(wasmCB.kvs, &types.KeyValue{
Key: wasmCB.formatStateKey(key),
Value: value,
})
}
func getStateDBSize(key []byte) int {
value, err := getStateDB(key)
if err != nil {
return 0
}
return len(value)
}
func getStateDB(key []byte) ([]byte, error) {
return wasmCB.GetStateDB().Get(wasmCB.formatStateKey(key))
}
func setLocalDB(key, value []byte) {
preValue, _ := getLocalDB(key)
wasmCB.receiptLogs = append(wasmCB.receiptLogs, &types.ReceiptLog{
Ty: types2.TyLogLocalData,
Log: types.Encode(&types2.LocalDataLog{
Key: wasmCB.formatLocalKey(key),
PreValue: preValue,
CurValue: value,
}),
})
}
func getLocalDBSize(key []byte) int {
value, err := getLocalDB(key)
if err != nil {
return 0
}
return len(value)
}
func getLocalDB(key []byte) ([]byte, error) {
return wasmCB.GetLocalDB().Get(wasmCB.formatLocalKey(key))
}
func execFrozen(addr string, amount int64) error {
receipt, err := wasmCB.GetCoinsAccount().ExecFrozen(addr, wasmCB.execAddr, amount)
if err != nil {
return err
}
wasmCB.kvs = append(wasmCB.kvs, receipt.KV...)
wasmCB.receiptLogs = append(wasmCB.receiptLogs, receipt.Logs...)
return nil
}
func execActive(addr string, amount int64) error {
receipt, err := wasmCB.GetCoinsAccount().ExecActive(addr, wasmCB.execAddr, amount)
if err != nil {
return err
}
wasmCB.kvs = append(wasmCB.kvs, receipt.KV...)
wasmCB.receiptLogs = append(wasmCB.receiptLogs, receipt.Logs...)
return nil
}
func execTransfer(from, to string, amount int64) error {
receipt, err := wasmCB.GetCoinsAccount().ExecTransfer(from, to, wasmCB.execAddr, amount)
if err != nil {
return err
}
wasmCB.kvs = append(wasmCB.kvs, receipt.KV...)
wasmCB.receiptLogs = append(wasmCB.receiptLogs, receipt.Logs...)
return nil
}
func execTransferFrozen(from, to string, amount int64) error {
receipt, err := wasmCB.GetCoinsAccount().ExecTransferFrozen(from, to, wasmCB.execAddr, amount)
if err != nil {
return err
}
wasmCB.kvs = append(wasmCB.kvs, receipt.KV...)
wasmCB.receiptLogs = append(wasmCB.receiptLogs, receipt.Logs...)
return nil
}
func getFrom() string {
return wasmCB.tx.From()
}
func getHeight() int64 {
return wasmCB.GetHeight()
}
func getRandom() int64 {
req := &types.ReqRandHash{
ExecName: "ticket",
BlockNum: 5,
Hash: wasmCB.GetLastHash(),
}
hash, err := wasmCB.GetExecutorAPI().GetRandNum(req)
if err != nil {
return -1
}
var rand int64
for _, c := range hash {
rand = rand*256 + int64(c)
}
return rand
}
func printlog(s string) {
wasmCB.logs = append(wasmCB.logs, s)
}
package executor
import (
"fmt"
"github.com/33cn/chain33/common/address"
)
const (
KeyPrefixContract = "mavl-wasm-%s:%s"
KeyPrefixLocal = "LODB-wasm-%s:%s"
)
func contractKey(name string) []byte {
contractAddr := address.ExecAddress(name)
key := "mavl-wasm-address:" + contractAddr
return []byte(key)
}
func (w *Wasm) formatStateKey(key []byte) []byte {
addr := address.ExecAddress(w.contractAddr)
return []byte(fmt.Sprintf(KeyPrefixContract, addr, string(key)))
}
func (w *Wasm) formatLocalKey(key []byte) []byte {
addr := address.ExecAddress(w.contractAddr)
return []byte(fmt.Sprintf(KeyPrefixLocal, addr, string(key)))
}
func (w *Wasm) contractExist(name string) bool {
_, err := w.GetStateDB().Get(contractKey(name))
return err == nil
}
func (w *Wasm) getContract(name string) ([]byte, error) {
return w.GetStateDB().Get(contractKey(name))
}
package executor
import (
"encoding/hex"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types"
types2 "github.com/33cn/plugin/plugin/dapp/wasm/types"
"github.com/perlin-network/life/compiler"
"github.com/perlin-network/life/exec"
validation "github.com/perlin-network/life/wasm-validation"
)
var wasmCB *Wasm
func (w *Wasm) Exec_Create(payload *types2.WasmCreate, tx *types.Transaction, index int) (*types.Receipt, error) {
if payload == nil {
return nil, types.ErrInvalidParam
}
name := payload.Name
if !validateName(name) {
return nil, types2.ErrInvalidContractName
}
if w.contractExist(name) {
return nil, types2.ErrContractExist
}
code := payload.Code
if len(code) > 1<<20 { //TODO: max size to define
return nil, types2.ErrCodeOversize
}
if err := validation.ValidateWasm(code); err != nil {
return nil, types2.ErrInvalidWasm
}
var receiptLogs []*types.ReceiptLog
kv := []*types.KeyValue{{
Key: contractKey(name),
Value: code,
}}
receiptLog := &types.ReceiptLog{
Ty: types2.TyLogWasmCreate,
Log: types.Encode(&types2.CreateContractLog{
Name: name,
Code: hex.EncodeToString(code),
}),
}
receiptLogs = append(receiptLogs, receiptLog)
return &types.Receipt{
Ty: types.ExecOk,
KV: kv,
Logs: receiptLogs,
}, nil
}
func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index int) (*types.Receipt, error) {
if payload == nil {
return nil, types.ErrInvalidParam
}
code, err := w.getContract(payload.Contract)
if err != nil {
return nil, err
}
vm, err := exec.NewVirtualMachine(code, exec.VMConfig{
DefaultMemoryPages: 128,
DefaultTableSize: 128,
DisableFloatingPoint: true,
GasLimit: uint64(tx.Fee),
}, new(Resolver), &compiler.SimpleGasPolicy{GasPerInstruction: 1})
if err != nil {
return nil, err
}
// Get the function ID of the entry function to be executed.
entryID, ok := vm.GetFunctionExport(payload.Method)
if !ok {
return nil, types2.ErrInvalidMethod
}
w.contractAddr = address.ExecAddress(payload.Contract)
w.tx = tx
w.execAddr = address.ExecAddress(string(tx.Execer))
wasmCB = w
defer func() {
wasmCB = nil
}()
// Run the WebAssembly module's entry function.
ret, err := vm.RunWithGasLimit(entryID, int(tx.Fee), payload.Parameters...)
if err != nil {
return nil, err
}
var logs []*types.ReceiptLog
logs = append(logs, &types.ReceiptLog{Ty: types2.TyLogWasmCall, Log: types.Encode(&types2.CallContractLog{
Contract: payload.Contract,
Method: payload.Method,
Result: ret,
})})
logs = append(logs, &types.ReceiptLog{Ty: types2.TyLogCustom, Log: types.Encode(&types2.CustomLog{
Info: w.logs,
})})
logs = append(logs, w.receiptLogs...)
return &types.Receipt{
Ty: types.ExecOk,
KV: w.kvs,
Logs: logs,
}, nil
}
func validateName(name string) bool {
if !types2.NameReg.MatchString(name) || len(name) < 4 || len(name) > 20 {
return false
}
return true
}
package executor
import (
"github.com/33cn/chain33/types"
types2 "github.com/33cn/plugin/plugin/dapp/wasm/types"
)
func (w *Wasm) ExecDelLocal_Create(payload *types2.WasmCreate, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return execDelLocal(receipt)
}
func (w *Wasm) ExecDelLocal_Call(payload *types2.WasmCall, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return execDelLocal(receipt)
}
func execDelLocal(receipt *types.ReceiptData) (*types.LocalDBSet, error) {
if receipt.Ty != types.ExecOk {
return nil, nil
}
set := &types.LocalDBSet{}
for _, item := range receipt.Logs {
if item.Ty == types2.TyLogLocalData {
var data types2.LocalDataLog
err := types.Decode(item.Log, &data)
if err != nil {
log.Error("execLocal", "decode error", err)
continue
}
set.KV = append(set.KV, &types.KeyValue{Key: data.Key, Value: data.PreValue})
}
}
return set, nil
}
package executor
import (
"github.com/33cn/chain33/types"
types2 "github.com/33cn/plugin/plugin/dapp/wasm/types"
)
func (w *Wasm) ExecLocal_Create(payload *types2.WasmCreate, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return execLocal(receipt)
}
func (w *Wasm) ExecLocal_Call(payload *types2.WasmCall, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return execLocal(receipt)
}
func execLocal(receipt *types.ReceiptData) (*types.LocalDBSet, error) {
if receipt.Ty != types.ExecOk {
return nil, nil
}
set := &types.LocalDBSet{}
for _, item := range receipt.Logs {
if item.Ty == types2.TyLogLocalData {
var data types2.LocalDataLog
err := types.Decode(item.Log, &data)
if err != nil {
log.Error("execLocal", "decode error", err)
continue
}
set.KV = append(set.KV, &types.KeyValue{Key: data.Key, Value: data.CurValue})
}
}
return set, nil
}
package executor
import (
"github.com/33cn/chain33/types"
types2 "github.com/33cn/plugin/plugin/dapp/wasm/types"
)
func (w *Wasm) Query_Check(query *types2.QueryCheckConract) (types.Message, error) {
if query == nil {
return nil, types.ErrInvalidParam
}
return &types.Reply{IsOk: w.contractExist(query.Name)}, nil
}
//func (w *Wasm) Query_CreateTransaction(query *types2.QueryCreateTransaction) (types.Message, error) {
// if query == nil {
// return nil, types.ErrInvalidParam
// }
// if !validateName(query.Name) {
// return nil, types2.ErrInvalidContractName
// }
//
// var action *types2.WasmAction
// switch query.Ty {
// case types2.WasmActionCreate:
// action = &types2.WasmAction{
// Value: &types2.WasmAction_Create{
// Create: &types2.WasmCreate{
// Name: query.Name,
// Code: query.Code,
// },
// },
// }
// case types2.WasmActionCall:
// action = &types2.WasmAction{
// Value: &types2.WasmAction_Call{
// Call: &types2.WasmCall{
// Contract: query.Name,
// Method: query.Method,
// Parameters: query.Parameters,
// },
// },
// }
// }
// if action == nil {
// return nil, types.ErrInvalidParam
// }
// cfg := w.GetAPI().GetConfig()
// tx := &types.Transaction{
// Payload: types.Encode(action),
// }
// tx, err := types.FormatTx(w.GetAPI().GetConfig(), cfg.ExecName(types2.WasmX), tx)
// if err != nil {
// return nil, err
// }
// if tx.Fee < query.Fee {
// tx.Fee = query.Fee
// }
// resp := types.ReplyString{
// Data: common.ToHex(types.Encode(tx)),
// }
// return &resp, nil
//}
package executor
import (
"fmt"
"github.com/perlin-network/life/exec"
)
// Resolver defines imports for WebAssembly modules ran in Life.
type Resolver struct{}
// ResolveFunc defines a set of import functions that may be called within a WebAssembly module.
func (r *Resolver) ResolveFunc(module, field string) exec.FunctionImport {
switch module {
case "env":
switch field {
case "setStateDB":
return func(vm *exec.VirtualMachine) int64 {
keyPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
keyLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
key := vm.Memory[keyPtr : keyPtr+keyLen]
valuePtr := int(uint32(vm.GetCurrentFrame().Locals[2]))
valueLen := int(uint32(vm.GetCurrentFrame().Locals[3]))
value := vm.Memory[valuePtr : valuePtr+valueLen]
setStateDB(key, value)
return 0
}
case "getStateDBSize":
return func(vm *exec.VirtualMachine) int64 {
keyPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
keyLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
key := vm.Memory[keyPtr : keyPtr+keyLen]
return int64(getStateDBSize(key))
}
case "getStateDB":
return func(vm *exec.VirtualMachine) int64 {
keyPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
keyLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
key := vm.Memory[keyPtr : keyPtr+keyLen]
valuePtr := int(uint32(vm.GetCurrentFrame().Locals[2]))
valueLen := int(uint32(vm.GetCurrentFrame().Locals[3]))
value, err := getStateDB(key)
if err != nil {
for i := 0; i < valueLen; i++ {
vm.Memory[valuePtr+i] = 0
}
return 0
}
if valueLen != len(value) {
return 0
}
for i, c := range value {
vm.Memory[valuePtr+i] = c
}
return int64(valueLen)
}
case "setLocalDB":
return func(vm *exec.VirtualMachine) int64 {
keyPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
keyLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
key := vm.Memory[keyPtr : keyPtr+keyLen]
valuePtr := int(uint32(vm.GetCurrentFrame().Locals[2]))
valueLen := int(uint32(vm.GetCurrentFrame().Locals[3]))
value := vm.Memory[valuePtr : valuePtr+valueLen]
setLocalDB(key, value)
return 0
}
case "getLocalDBSize":
return func(vm *exec.VirtualMachine) int64 {
keyPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
keyLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
key := vm.Memory[keyPtr : keyPtr+keyLen]
return int64(getLocalDBSize(key))
}
case "getLocalDB":
return func(vm *exec.VirtualMachine) int64 {
keyPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
keyLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
key := vm.Memory[keyPtr : keyPtr+keyLen]
valuePtr := int(uint32(vm.GetCurrentFrame().Locals[2]))
valueLen := int(uint32(vm.GetCurrentFrame().Locals[3]))
value, err := getLocalDB(key)
if err != nil {
for i := 0; i < valueLen; i++ {
vm.Memory[valuePtr+i] = 0
}
return 0
}
if valueLen != len(value) {
return 0
}
for i, c := range value {
vm.Memory[valuePtr+i] = c
}
return int64(valueLen)
}
case "execFrozen":
return func(vm *exec.VirtualMachine) int64 {
addrPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
addrLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
addr := string(vm.Memory[addrPtr : addrPtr+addrLen])
amount := vm.GetCurrentFrame().Locals[2]
err := execFrozen(addr, amount)
if err != nil {
return -1
}
return 0
}
case "execActive":
return func(vm *exec.VirtualMachine) int64 {
addrPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
addrLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
addr := string(vm.Memory[addrPtr : addrPtr+addrLen])
amount := vm.GetCurrentFrame().Locals[2]
err := execActive(addr, amount)
if err != nil {
return -1
}
return 0
}
case "execTransfer":
return func(vm *exec.VirtualMachine) int64 {
fromPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
fromLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
fromAddr := string(vm.Memory[fromPtr : fromPtr+fromLen])
toPtr := int(uint32(vm.GetCurrentFrame().Locals[2]))
toLen := int(uint32(vm.GetCurrentFrame().Locals[3]))
toAddr := string(vm.Memory[toPtr : toPtr+toLen])
amount := vm.GetCurrentFrame().Locals[4]
err := execTransfer(fromAddr, toAddr, amount)
if err != nil {
return -1
}
return 0
}
case "execTransferFrozen":
return func(vm *exec.VirtualMachine) int64 {
fromPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
fromLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
fromAddr := string(vm.Memory[fromPtr : fromPtr+fromLen])
toPtr := int(uint32(vm.GetCurrentFrame().Locals[2]))
toLen := int(uint32(vm.GetCurrentFrame().Locals[3]))
toAddr := string(vm.Memory[toPtr : toPtr+toLen])
amount := vm.GetCurrentFrame().Locals[4]
err := execTransferFrozen(fromAddr, toAddr, amount)
if err != nil {
return -1
}
return 0
}
case "getFrom":
return func(vm *exec.VirtualMachine) int64 {
fromAddr := []byte(getFrom())
fromPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
fromLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
copy(vm.Memory[fromPtr:fromPtr+fromLen], fromAddr)
return 0
}
case "getHeight":
return func(vm *exec.VirtualMachine) int64 {
return getHeight()
}
case "getRandom":
return func(vm *exec.VirtualMachine) int64 {
return getRandom()
}
case "printlog":
return func(vm *exec.VirtualMachine) int64 {
fmt.Println(vm.GetCurrentFrame().Locals)
logPtr := int(uint32(vm.GetCurrentFrame().Locals[0]))
logLen := int(uint32(vm.GetCurrentFrame().Locals[1]))
logInfo := string(vm.Memory[logPtr : logPtr+logLen])
printlog(logInfo)
return 0
}
default:
panic(fmt.Errorf("unknown field: %s", field))
}
default:
panic(fmt.Errorf("unknown module: %s", module))
}
}
// ResolveGlobal defines a set of global variables for use within a WebAssembly module.
func (r *Resolver) ResolveGlobal(module, field string) int64 {
fmt.Printf("Resolve global: %s %s\n", module, field)
switch module {
case "env":
switch field {
case "__life_magic":
return 424
default:
panic(fmt.Errorf("unknown field: %s", field))
}
default:
panic(fmt.Errorf("unknown module: %s", module))
}
}
package executor
import (
"github.com/33cn/chain33/common/log/log15"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
types2 "github.com/33cn/plugin/plugin/dapp/wasm/types"
)
var driverName = types2.WasmX
var log = log15.New("module", "execs."+types2.WasmX)
func Init(name string, cfg *types.Chain33Config, sub []byte) {
if name != driverName {
panic("system dapp can not be rename")
}
drivers.Register(cfg, name, newWasm, cfg.GetDappFork(name, "Enable"))
initExecType()
}
func initExecType() {
ety := types.LoadExecutorType(driverName)
ety.InitFuncList(types.ListMethod(&Wasm{}))
}
type Wasm struct {
drivers.DriverBase
tx *types.Transaction
kvs []*types.KeyValue
receiptLogs []*types.ReceiptLog
logs []string
execAddr string
contractAddr string
}
func newWasm() drivers.Driver {
d := &Wasm{}
d.SetChild(d)
d.SetExecutorType(types.LoadExecutorType(driverName))
return d
}
// GetName 获取执行器别名
func GetName() string {
return newWasm().GetName()
}
func (w *Wasm) GetDriverName() string {
return driverName
}
package wasm
import (
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/wasm/commands"
"github.com/33cn/plugin/plugin/dapp/wasm/executor"
_ "github.com/33cn/plugin/plugin/dapp/wasm/rpc"
"github.com/33cn/plugin/plugin/dapp/wasm/types"
)
func init() {
pluginmgr.Register(&pluginmgr.PluginBase{
Name: types.WasmX,
ExecName: executor.GetName(),
Exec: executor.Init,
Cmd: commands.Cmd,
//RPC: rpc.Init,
})
}
all:
sh ./create_protobuf.sh
#!/bin/sh
chain33_path=$(go list -f '{{.Dir}}' "github.com/33cn/chain33")
protoc --go_out=plugins=grpc:../types ./*.proto --proto_path=. --proto_path="${chain33_path}/types/proto/"
syntax = "proto3";
package types;
message wasmAction {
oneof value {
wasmCreate create = 1;
wasmCall call = 2;
}
int32 ty = 3;
}
message wasmCreate {
string name = 1;
bytes code = 2;
}
message wasmCall {
string contract = 1;
string method = 2;
repeated int64 parameters = 3;
}
message queryCheckConract {
string name = 1;
}
message queryCreateTransaction{
int32 ty = 1;
string name = 2;
bytes code = 3;
string method = 4;
repeated int64 parameters = 5;
int64 fee = 6;
}
message customLog {
repeated string info = 1;
}
message createContractLog {
string name = 1;
string code = 2;
}
message callContractLog {
string contract = 1;
string method = 2;
int64 result = 3;
}
message localDataLog {
bytes key = 1;
bytes preValue = 2;
bytes curValue = 3;
}
package types
import "errors"
var (
ErrContractExist = errors.New("contract exist")
ErrInvalidWasm = errors.New("invalid wasm code")
ErrCodeOversize = errors.New("code oversize")
ErrInvalidMethod = errors.New("invalid method")
ErrInvalidContractName = errors.New("invalid contract name")
)
package types
import (
"reflect"
"regexp"
"github.com/33cn/chain33/types"
)
var NameReg *regexp.Regexp
const (
WasmX = "wasm"
NameRegExp = "^[a-z0-9]+$"
)
// action for executor
const (
WasmActionCreate = iota + 1
WasmActionCall
)
// log ty for executor
const (
TyLogWasmCreate = iota + 100
TyLogWasmCall
TyLogCustom
TyLogLocalData
)
func init() {
types.AllowUserExec = append(types.AllowUserExec, []byte(WasmX))
types.RegFork(WasmX, InitFork)
types.RegExec(WasmX, InitExecutor)
NameReg, _ = regexp.Compile(NameRegExp)
}
func InitFork(cfg *types.Chain33Config) {
cfg.RegisterDappFork(WasmX, "Enable", 0)
}
func InitExecutor(cfg *types.Chain33Config) {
types.RegistorExecutor(WasmX, NewType(cfg))
}
type WasmType struct {
types.ExecTypeBase
}
func NewType(cfg *types.Chain33Config) *WasmType {
c := &WasmType{}
c.SetChild(c)
c.SetConfig(cfg)
return c
}
func (t *WasmType) GetPayload() types.Message {
return &WasmAction{}
}
func (t *WasmType) GetTypeMap() map[string]int32 {
return map[string]int32{
"Create": WasmActionCreate,
"Call": WasmActionCall,
}
}
func (t *WasmType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogWasmCreate: {Ty: reflect.TypeOf(CreateContractLog{}), Name: "LogWasmCreate"},
TyLogWasmCall: {Ty: reflect.TypeOf(CallContractLog{}), Name: "LogWasmCall"},
TyLogCustom: {Ty: reflect.TypeOf(CustomLog{}), Name: "LogWasmCustom"},
TyLogLocalData: {Ty: reflect.TypeOf(LocalDataLog{}), Name: "LogWasmLocalData"},
}
}
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: wasm.proto
package types
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type WasmAction struct {
// Types that are valid to be assigned to Value:
// *WasmAction_Create
// *WasmAction_Call
Value isWasmAction_Value `protobuf_oneof:"value"`
Ty int32 `protobuf:"varint,3,opt,name=ty,proto3" json:"ty,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *WasmAction) Reset() { *m = WasmAction{} }
func (m *WasmAction) String() string { return proto.CompactTextString(m) }
func (*WasmAction) ProtoMessage() {}
func (*WasmAction) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{0}
}
func (m *WasmAction) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_WasmAction.Unmarshal(m, b)
}
func (m *WasmAction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_WasmAction.Marshal(b, m, deterministic)
}
func (m *WasmAction) XXX_Merge(src proto.Message) {
xxx_messageInfo_WasmAction.Merge(m, src)
}
func (m *WasmAction) XXX_Size() int {
return xxx_messageInfo_WasmAction.Size(m)
}
func (m *WasmAction) XXX_DiscardUnknown() {
xxx_messageInfo_WasmAction.DiscardUnknown(m)
}
var xxx_messageInfo_WasmAction proto.InternalMessageInfo
type isWasmAction_Value interface {
isWasmAction_Value()
}
type WasmAction_Create struct {
Create *WasmCreate `protobuf:"bytes,1,opt,name=create,proto3,oneof"`
}
type WasmAction_Call struct {
Call *WasmCall `protobuf:"bytes,2,opt,name=call,proto3,oneof"`
}
func (*WasmAction_Create) isWasmAction_Value() {}
func (*WasmAction_Call) isWasmAction_Value() {}
func (m *WasmAction) GetValue() isWasmAction_Value {
if m != nil {
return m.Value
}
return nil
}
func (m *WasmAction) GetCreate() *WasmCreate {
if x, ok := m.GetValue().(*WasmAction_Create); ok {
return x.Create
}
return nil
}
func (m *WasmAction) GetCall() *WasmCall {
if x, ok := m.GetValue().(*WasmAction_Call); ok {
return x.Call
}
return nil
}
func (m *WasmAction) GetTy() int32 {
if m != nil {
return m.Ty
}
return 0
}
// XXX_OneofWrappers is for the internal use of the proto package.
func (*WasmAction) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*WasmAction_Create)(nil),
(*WasmAction_Call)(nil),
}
}
type WasmCreate struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Code []byte `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *WasmCreate) Reset() { *m = WasmCreate{} }
func (m *WasmCreate) String() string { return proto.CompactTextString(m) }
func (*WasmCreate) ProtoMessage() {}
func (*WasmCreate) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{1}
}
func (m *WasmCreate) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_WasmCreate.Unmarshal(m, b)
}
func (m *WasmCreate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_WasmCreate.Marshal(b, m, deterministic)
}
func (m *WasmCreate) XXX_Merge(src proto.Message) {
xxx_messageInfo_WasmCreate.Merge(m, src)
}
func (m *WasmCreate) XXX_Size() int {
return xxx_messageInfo_WasmCreate.Size(m)
}
func (m *WasmCreate) XXX_DiscardUnknown() {
xxx_messageInfo_WasmCreate.DiscardUnknown(m)
}
var xxx_messageInfo_WasmCreate proto.InternalMessageInfo
func (m *WasmCreate) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *WasmCreate) GetCode() []byte {
if m != nil {
return m.Code
}
return nil
}
type WasmCall struct {
Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Parameters []int64 `protobuf:"varint,3,rep,packed,name=parameters,proto3" json:"parameters,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *WasmCall) Reset() { *m = WasmCall{} }
func (m *WasmCall) String() string { return proto.CompactTextString(m) }
func (*WasmCall) ProtoMessage() {}
func (*WasmCall) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{2}
}
func (m *WasmCall) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_WasmCall.Unmarshal(m, b)
}
func (m *WasmCall) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_WasmCall.Marshal(b, m, deterministic)
}
func (m *WasmCall) XXX_Merge(src proto.Message) {
xxx_messageInfo_WasmCall.Merge(m, src)
}
func (m *WasmCall) XXX_Size() int {
return xxx_messageInfo_WasmCall.Size(m)
}
func (m *WasmCall) XXX_DiscardUnknown() {
xxx_messageInfo_WasmCall.DiscardUnknown(m)
}
var xxx_messageInfo_WasmCall proto.InternalMessageInfo
func (m *WasmCall) GetContract() string {
if m != nil {
return m.Contract
}
return ""
}
func (m *WasmCall) GetMethod() string {
if m != nil {
return m.Method
}
return ""
}
func (m *WasmCall) GetParameters() []int64 {
if m != nil {
return m.Parameters
}
return nil
}
type QueryCheckConract struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *QueryCheckConract) Reset() { *m = QueryCheckConract{} }
func (m *QueryCheckConract) String() string { return proto.CompactTextString(m) }
func (*QueryCheckConract) ProtoMessage() {}
func (*QueryCheckConract) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{3}
}
func (m *QueryCheckConract) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryCheckConract.Unmarshal(m, b)
}
func (m *QueryCheckConract) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_QueryCheckConract.Marshal(b, m, deterministic)
}
func (m *QueryCheckConract) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryCheckConract.Merge(m, src)
}
func (m *QueryCheckConract) XXX_Size() int {
return xxx_messageInfo_QueryCheckConract.Size(m)
}
func (m *QueryCheckConract) XXX_DiscardUnknown() {
xxx_messageInfo_QueryCheckConract.DiscardUnknown(m)
}
var xxx_messageInfo_QueryCheckConract proto.InternalMessageInfo
func (m *QueryCheckConract) GetName() string {
if m != nil {
return m.Name
}
return ""
}
type QueryCreateTransaction struct {
Ty int32 `protobuf:"varint,1,opt,name=ty,proto3" json:"ty,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Code []byte `protobuf:"bytes,3,opt,name=code,proto3" json:"code,omitempty"`
Method string `protobuf:"bytes,4,opt,name=method,proto3" json:"method,omitempty"`
Parameters []int64 `protobuf:"varint,5,rep,packed,name=parameters,proto3" json:"parameters,omitempty"`
Fee int64 `protobuf:"varint,6,opt,name=fee,proto3" json:"fee,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *QueryCreateTransaction) Reset() { *m = QueryCreateTransaction{} }
func (m *QueryCreateTransaction) String() string { return proto.CompactTextString(m) }
func (*QueryCreateTransaction) ProtoMessage() {}
func (*QueryCreateTransaction) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{4}
}
func (m *QueryCreateTransaction) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryCreateTransaction.Unmarshal(m, b)
}
func (m *QueryCreateTransaction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_QueryCreateTransaction.Marshal(b, m, deterministic)
}
func (m *QueryCreateTransaction) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryCreateTransaction.Merge(m, src)
}
func (m *QueryCreateTransaction) XXX_Size() int {
return xxx_messageInfo_QueryCreateTransaction.Size(m)
}
func (m *QueryCreateTransaction) XXX_DiscardUnknown() {
xxx_messageInfo_QueryCreateTransaction.DiscardUnknown(m)
}
var xxx_messageInfo_QueryCreateTransaction proto.InternalMessageInfo
func (m *QueryCreateTransaction) GetTy() int32 {
if m != nil {
return m.Ty
}
return 0
}
func (m *QueryCreateTransaction) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *QueryCreateTransaction) GetCode() []byte {
if m != nil {
return m.Code
}
return nil
}
func (m *QueryCreateTransaction) GetMethod() string {
if m != nil {
return m.Method
}
return ""
}
func (m *QueryCreateTransaction) GetParameters() []int64 {
if m != nil {
return m.Parameters
}
return nil
}
func (m *QueryCreateTransaction) GetFee() int64 {
if m != nil {
return m.Fee
}
return 0
}
type CustomLog struct {
Info []string `protobuf:"bytes,1,rep,name=info,proto3" json:"info,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CustomLog) Reset() { *m = CustomLog{} }
func (m *CustomLog) String() string { return proto.CompactTextString(m) }
func (*CustomLog) ProtoMessage() {}
func (*CustomLog) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{5}
}
func (m *CustomLog) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CustomLog.Unmarshal(m, b)
}
func (m *CustomLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CustomLog.Marshal(b, m, deterministic)
}
func (m *CustomLog) XXX_Merge(src proto.Message) {
xxx_messageInfo_CustomLog.Merge(m, src)
}
func (m *CustomLog) XXX_Size() int {
return xxx_messageInfo_CustomLog.Size(m)
}
func (m *CustomLog) XXX_DiscardUnknown() {
xxx_messageInfo_CustomLog.DiscardUnknown(m)
}
var xxx_messageInfo_CustomLog proto.InternalMessageInfo
func (m *CustomLog) GetInfo() []string {
if m != nil {
return m.Info
}
return nil
}
type CreateContractLog struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CreateContractLog) Reset() { *m = CreateContractLog{} }
func (m *CreateContractLog) String() string { return proto.CompactTextString(m) }
func (*CreateContractLog) ProtoMessage() {}
func (*CreateContractLog) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{6}
}
func (m *CreateContractLog) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CreateContractLog.Unmarshal(m, b)
}
func (m *CreateContractLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CreateContractLog.Marshal(b, m, deterministic)
}
func (m *CreateContractLog) XXX_Merge(src proto.Message) {
xxx_messageInfo_CreateContractLog.Merge(m, src)
}
func (m *CreateContractLog) XXX_Size() int {
return xxx_messageInfo_CreateContractLog.Size(m)
}
func (m *CreateContractLog) XXX_DiscardUnknown() {
xxx_messageInfo_CreateContractLog.DiscardUnknown(m)
}
var xxx_messageInfo_CreateContractLog proto.InternalMessageInfo
func (m *CreateContractLog) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *CreateContractLog) GetCode() string {
if m != nil {
return m.Code
}
return ""
}
type CallContractLog struct {
Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Result int64 `protobuf:"varint,3,opt,name=result,proto3" json:"result,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CallContractLog) Reset() { *m = CallContractLog{} }
func (m *CallContractLog) String() string { return proto.CompactTextString(m) }
func (*CallContractLog) ProtoMessage() {}
func (*CallContractLog) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{7}
}
func (m *CallContractLog) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CallContractLog.Unmarshal(m, b)
}
func (m *CallContractLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CallContractLog.Marshal(b, m, deterministic)
}
func (m *CallContractLog) XXX_Merge(src proto.Message) {
xxx_messageInfo_CallContractLog.Merge(m, src)
}
func (m *CallContractLog) XXX_Size() int {
return xxx_messageInfo_CallContractLog.Size(m)
}
func (m *CallContractLog) XXX_DiscardUnknown() {
xxx_messageInfo_CallContractLog.DiscardUnknown(m)
}
var xxx_messageInfo_CallContractLog proto.InternalMessageInfo
func (m *CallContractLog) GetContract() string {
if m != nil {
return m.Contract
}
return ""
}
func (m *CallContractLog) GetMethod() string {
if m != nil {
return m.Method
}
return ""
}
func (m *CallContractLog) GetResult() int64 {
if m != nil {
return m.Result
}
return 0
}
type LocalDataLog struct {
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
PreValue []byte `protobuf:"bytes,2,opt,name=preValue,proto3" json:"preValue,omitempty"`
CurValue []byte `protobuf:"bytes,3,opt,name=curValue,proto3" json:"curValue,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *LocalDataLog) Reset() { *m = LocalDataLog{} }
func (m *LocalDataLog) String() string { return proto.CompactTextString(m) }
func (*LocalDataLog) ProtoMessage() {}
func (*LocalDataLog) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{8}
}
func (m *LocalDataLog) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LocalDataLog.Unmarshal(m, b)
}
func (m *LocalDataLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_LocalDataLog.Marshal(b, m, deterministic)
}
func (m *LocalDataLog) XXX_Merge(src proto.Message) {
xxx_messageInfo_LocalDataLog.Merge(m, src)
}
func (m *LocalDataLog) XXX_Size() int {
return xxx_messageInfo_LocalDataLog.Size(m)
}
func (m *LocalDataLog) XXX_DiscardUnknown() {
xxx_messageInfo_LocalDataLog.DiscardUnknown(m)
}
var xxx_messageInfo_LocalDataLog proto.InternalMessageInfo
func (m *LocalDataLog) GetKey() []byte {
if m != nil {
return m.Key
}
return nil
}
func (m *LocalDataLog) GetPreValue() []byte {
if m != nil {
return m.PreValue
}
return nil
}
func (m *LocalDataLog) GetCurValue() []byte {
if m != nil {
return m.CurValue
}
return nil
}
func init() {
proto.RegisterType((*WasmAction)(nil), "types.wasmAction")
proto.RegisterType((*WasmCreate)(nil), "types.wasmCreate")
proto.RegisterType((*WasmCall)(nil), "types.wasmCall")
proto.RegisterType((*QueryCheckConract)(nil), "types.queryCheckConract")
proto.RegisterType((*QueryCreateTransaction)(nil), "types.queryCreateTransaction")
proto.RegisterType((*CustomLog)(nil), "types.customLog")
proto.RegisterType((*CreateContractLog)(nil), "types.createContractLog")
proto.RegisterType((*CallContractLog)(nil), "types.callContractLog")
proto.RegisterType((*LocalDataLog)(nil), "types.localDataLog")
}
func init() { proto.RegisterFile("wasm.proto", fileDescriptor_7d78909ad64e3bbb) }
var fileDescriptor_7d78909ad64e3bbb = []byte{
// 393 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x52, 0x3d, 0x0f, 0xd3, 0x30,
0x10, 0x6d, 0xe2, 0x26, 0x34, 0x47, 0x45, 0x5b, 0x0f, 0x55, 0xc4, 0x00, 0x91, 0x25, 0x44, 0x24,
0xa4, 0x0e, 0xc0, 0xc6, 0x04, 0x61, 0xe8, 0xc0, 0x64, 0x21, 0xc4, 0x02, 0x92, 0x71, 0x5d, 0x5a,
0xd5, 0x89, 0x83, 0xe3, 0x80, 0xf2, 0x57, 0xf8, 0xb5, 0xc8, 0x1f, 0x0d, 0x11, 0xaa, 0x3a, 0xb0,
0xdd, 0xc7, 0xbb, 0x7b, 0x77, 0xf7, 0x0e, 0xe0, 0x17, 0xeb, 0xea, 0x5d, 0xab, 0x95, 0x51, 0x38,
0x31, 0x43, 0x2b, 0x3a, 0x32, 0xf8, 0xe0, 0x5b, 0x6e, 0xce, 0xaa, 0xc1, 0x2f, 0x20, 0xe5, 0x5a,
0x30, 0x23, 0xf2, 0xa8, 0x88, 0xca, 0x87, 0x2f, 0x37, 0x3b, 0x87, 0xda, 0x59, 0x48, 0xe5, 0x12,
0xfb, 0x19, 0x0d, 0x10, 0xfc, 0x0c, 0xe6, 0x9c, 0x49, 0x99, 0xc7, 0x0e, 0xba, 0x9a, 0x42, 0x99,
0x94, 0xfb, 0x19, 0x75, 0x69, 0xfc, 0x08, 0x62, 0x33, 0xe4, 0xa8, 0x88, 0xca, 0x84, 0xc6, 0x66,
0x78, 0xf7, 0x00, 0x92, 0x9f, 0x4c, 0xf6, 0x82, 0xbc, 0xf6, 0xd4, 0xbe, 0x2f, 0xc6, 0x30, 0x6f,
0x58, 0xed, 0x89, 0x33, 0xea, 0x6c, 0x1b, 0xe3, 0xea, 0x20, 0x1c, 0xc3, 0x92, 0x3a, 0x9b, 0x7c,
0x85, 0xc5, 0x95, 0x02, 0x3f, 0x86, 0x05, 0x57, 0x8d, 0xd1, 0x8c, 0x9b, 0x50, 0x37, 0xfa, 0x78,
0x0b, 0x69, 0x2d, 0xcc, 0x49, 0x1d, 0x5c, 0x75, 0x46, 0x83, 0x87, 0x9f, 0x00, 0xb4, 0x4c, 0xb3,
0x5a, 0x18, 0xa1, 0xbb, 0x1c, 0x15, 0xa8, 0x44, 0x74, 0x12, 0x21, 0xcf, 0x61, 0xf3, 0xa3, 0x17,
0x7a, 0xa8, 0x4e, 0x82, 0x5f, 0x2a, 0xd5, 0xb8, 0x66, 0x37, 0x86, 0x23, 0xbf, 0x23, 0xd8, 0x7a,
0xa4, 0x5b, 0xe0, 0xa3, 0x66, 0x4d, 0xc7, 0xfc, 0x19, 0xfd, 0xca, 0xd1, 0x75, 0xe5, 0xb1, 0x3c,
0xbe, 0xb1, 0x1b, 0xfa, 0xbb, 0xdb, 0x64, 0xe6, 0xf9, 0x9d, 0x99, 0x93, 0x7f, 0x67, 0xc6, 0x6b,
0x40, 0x47, 0x21, 0xf2, 0xb4, 0x88, 0x4a, 0x44, 0xad, 0x49, 0x9e, 0x42, 0xc6, 0xfb, 0xce, 0xa8,
0xfa, 0x83, 0xfa, 0x6e, 0xa9, 0xce, 0xcd, 0x51, 0xe5, 0x51, 0x81, 0x2c, 0xbd, 0xb5, 0xc9, 0x1b,
0xd8, 0x78, 0x19, 0xab, 0x70, 0xb0, 0x00, 0xbc, 0xab, 0x41, 0x16, 0x34, 0xf8, 0x02, 0x2b, 0x2b,
0xed, 0xb4, 0xf4, 0x7f, 0xa4, 0xd8, 0x42, 0xaa, 0x45, 0xd7, 0x4b, 0xe3, 0x8e, 0x80, 0x68, 0xf0,
0xc8, 0x67, 0x58, 0x4a, 0xc5, 0x99, 0x7c, 0xcf, 0x0c, 0xb3, 0xbd, 0xd7, 0x80, 0x2e, 0xc2, 0xdf,
0x73, 0x49, 0xad, 0x69, 0xd9, 0x5a, 0x2d, 0x3e, 0xd9, 0x37, 0x0a, 0xcf, 0x31, 0xfa, 0x6e, 0x92,
0x5e, 0xfb, 0x9c, 0x3f, 0xee, 0xe8, 0x7f, 0x4b, 0xdd, 0xef, 0xbf, 0xfa, 0x13, 0x00, 0x00, 0xff,
0xff, 0xb4, 0xb4, 0xce, 0xf0, 0x09, 0x03, 0x00, 0x00,
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment