Merge pull request #2698 from nspcc-dev/address-helpers
interop: add a couple of `interop.Hash160` encoding helpers
This commit is contained in:
commit
5a7ab2054d
33 changed files with 238 additions and 57 deletions
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/engine
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/events
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/iterator
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/nft
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
|
@ -3,8 +3,8 @@ module github.com/nspcc-dev/neo-go/examples/nft-nd-nns
|
|||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/nspcc-dev/neo-go v0.99.2-pre.0.20220809124015-119b40c37815
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
github.com/nspcc-dev/neo-go v0.99.4-0.20220920064337-0477f83ea87e
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
github.com/stretchr/testify v1.7.0
|
||||
)
|
||||
|
||||
|
|
|
@ -200,8 +200,10 @@ github.com/nspcc-dev/go-ordered-json v0.0.0-20220111165707-25110be27d22 h1:n4ZaF
|
|||
github.com/nspcc-dev/go-ordered-json v0.0.0-20220111165707-25110be27d22/go.mod h1:79bEUDEviBHJMFV6Iq6in57FEOCMcRhfQnfaf0ETA5U=
|
||||
github.com/nspcc-dev/neo-go v0.99.2-pre.0.20220809124015-119b40c37815 h1:tk05Q+2Fi6VRI6whnxrn5fh1cK1VKZ/MqLaLkCQzlPg=
|
||||
github.com/nspcc-dev/neo-go v0.99.2-pre.0.20220809124015-119b40c37815/go.mod h1:9P0yWqhZX7i/ChJ+zjtiStO1uPTolPFUM+L5oNznU8E=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go v0.99.4-0.20220920064337-0477f83ea87e h1:kWNDuDjY1TKa8CyFcRrhc+y6Vg466IyKznPb3bpm8dc=
|
||||
github.com/nspcc-dev/neo-go v0.99.4-0.20220920064337-0477f83ea87e/go.mod h1:sZxLhLjdbk1/YIUAfrGemaHLZmnq6H8lyQMfo75sNbw=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
|
||||
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/nft-nd
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/oracle
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/runtime
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/storage
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/timer
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/token
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
2
go.mod
2
go.mod
|
@ -13,7 +13,7 @@ require (
|
|||
github.com/mr-tron/base58 v1.2.0
|
||||
github.com/nspcc-dev/dbft v0.0.0-20220902113116-58a5e763e647
|
||||
github.com/nspcc-dev/go-ordered-json v0.0.0-20220111165707-25110be27d22
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20220113123743-7f3162110659
|
||||
github.com/nspcc-dev/rfc6979 v0.2.0
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible
|
||||
|
|
4
go.sum
4
go.sum
|
@ -260,8 +260,8 @@ github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
|
|||
github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
|
||||
github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg=
|
||||
github.com/nspcc-dev/neo-go v0.98.0/go.mod h1:E3cc1x6RXSXrJb2nDWXTXjnXk3rIqVN8YdFyWv+FrqM=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1 h1:SVqc523pZsSaS9vnPS1mm3VV6b6xY0gvdA0uYJ/GWZQ=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/oracle
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b h1:J7QZNmnO84esVuPbBo88fwAG4XVnDjlSTiO1ewLNCkQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220809123759-3094d3e0c14b/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2 h1:BC/DKmjW+ArkqXTQjbVt7XubCJnDiCenH0pUI15gUyQ=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220920063704-7e13140b04c2/go.mod h1:23bBw0v6pBYcrWs8CBEEDIEDJNbcFoIh8pGGcf2Vv8s=
|
||||
|
|
|
@ -28,6 +28,26 @@ var (
|
|||
customBuiltins = []string{
|
||||
"FromAddress",
|
||||
}
|
||||
// Custom builtin utility functions that contain some meaningful code inside and
|
||||
// require code generation using standard rules, but sometimes (depending on
|
||||
// the expression usage condition) may be optimized at compile time.
|
||||
potentialCustomBuiltins = map[string]func(f ast.Expr) bool{
|
||||
"ToHash160": func(f ast.Expr) bool {
|
||||
c, ok := f.(*ast.CallExpr)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if len(c.Args) != 1 {
|
||||
return false
|
||||
}
|
||||
switch c.Args[0].(type) {
|
||||
case *ast.BasicLit:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// newGlobal creates a new global variable.
|
||||
|
@ -634,6 +654,18 @@ func isCustomBuiltin(f *funcScope) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func isPotentialCustomBuiltin(f *funcScope, expr ast.Expr) bool {
|
||||
if !isInteropPath(f.pkg.Path()) {
|
||||
return false
|
||||
}
|
||||
for name, isBuiltin := range potentialCustomBuiltins {
|
||||
if f.name == name && isBuiltin(expr) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isSyscall(fun *funcScope) bool {
|
||||
if fun.selector == nil || fun.pkg == nil || !isInteropPath(fun.pkg.Path()) {
|
||||
return false
|
||||
|
@ -664,9 +696,10 @@ func canConvert(s string) bool {
|
|||
}
|
||||
|
||||
// canInline returns true if the function is to be inlined.
|
||||
// Currently, there is a static list of functions which are inlined,
|
||||
// this may change in future.
|
||||
func canInline(s string, name string) bool {
|
||||
// The list of functions that can be inlined is not static, it depends on the function usages.
|
||||
// isBuiltin denotes whether code generation for dynamic builtin function will be performed
|
||||
// manually.
|
||||
func canInline(s string, name string, isBuiltin bool) bool {
|
||||
if strings.HasPrefix(s, "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline") {
|
||||
return true
|
||||
}
|
||||
|
@ -674,5 +707,6 @@ func canInline(s string, name string) bool {
|
|||
return false
|
||||
}
|
||||
return !strings.HasPrefix(s[len(interopPrefix):], "/neogointernal") &&
|
||||
!(strings.HasPrefix(s[len(interopPrefix):], "/util") && name == "FromAddress")
|
||||
!(strings.HasPrefix(s[len(interopPrefix):], "/util") && name == "FromAddress") &&
|
||||
!(strings.HasPrefix(s[len(interopPrefix):], "/lib/address") && name == "ToHash160" && isBuiltin)
|
||||
}
|
||||
|
|
|
@ -456,6 +456,8 @@ func (c *codegen) convertFuncDecl(file ast.Node, decl *ast.FuncDecl, pkg *types.
|
|||
f, ok = c.funcs[c.getFuncNameFromDecl("", decl)]
|
||||
if ok {
|
||||
// If this function is a syscall or builtin we will not convert it to bytecode.
|
||||
// If it's a potential custom builtin then it needs more specific usages research,
|
||||
// thus let's emit the code for it.
|
||||
if isSyscall(f) || isCustomBuiltin(f) {
|
||||
return f
|
||||
}
|
||||
|
@ -947,7 +949,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
if fun.Obj != nil && fun.Obj.Kind == ast.Var {
|
||||
isFunc = true
|
||||
}
|
||||
if ok && canInline(f.pkg.Path(), f.decl.Name.Name) {
|
||||
if ok && canInline(f.pkg.Path(), f.decl.Name.Name, false) {
|
||||
c.inlineCall(f, n)
|
||||
return nil
|
||||
}
|
||||
|
@ -957,8 +959,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
f, ok = c.funcs[name]
|
||||
if ok {
|
||||
f.selector = fun.X
|
||||
isBuiltin = isCustomBuiltin(f)
|
||||
if canInline(f.pkg.Path(), f.decl.Name.Name) {
|
||||
isBuiltin = isCustomBuiltin(f) || isPotentialCustomBuiltin(f, n)
|
||||
if canInline(f.pkg.Path(), f.decl.Name.Name, isBuiltin) {
|
||||
c.inlineCall(f, n)
|
||||
return nil
|
||||
}
|
||||
|
@ -993,7 +995,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
|
||||
c.saveSequencePoint(n)
|
||||
|
||||
args := transformArgs(f, n.Fun, n.Args)
|
||||
args := transformArgs(f, n.Fun, isBuiltin, n.Args)
|
||||
|
||||
// Handle the arguments
|
||||
for _, arg := range args {
|
||||
|
@ -1870,8 +1872,8 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
|||
c.emitStoreByIndex(varGlobal, c.exceptionIndex)
|
||||
case "delete":
|
||||
emit.Opcodes(c.prog.BinWriter, opcode.REMOVE)
|
||||
case "FromAddress":
|
||||
// We can be sure that this is a ast.BasicLit just containing a simple
|
||||
case "FromAddress", "ToHash160":
|
||||
// We can be sure that this is an ast.BasicLit just containing a simple
|
||||
// address string. Note that the string returned from calling Value will
|
||||
// contain double quotes that need to be stripped.
|
||||
addressStr := expr.Args[0].(*ast.BasicLit).Value
|
||||
|
@ -1890,14 +1892,15 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
|||
// transformArgs returns a list of function arguments
|
||||
// which should be put on stack.
|
||||
// There are special cases for builtins:
|
||||
// 1. With FromAddress, parameter conversion is happening at compile-time
|
||||
// so there is no need to push parameters on stack and perform an actual call
|
||||
// 1. With FromAddress and with ToHash160 in case if it behaves like builtin,
|
||||
// parameter conversion is happening at compile-time so there is no need to
|
||||
// push parameters on stack and perform an actual call
|
||||
// 2. With panic, the generated code depends on the fact if an argument was nil or a string;
|
||||
// so, it should be handled accordingly.
|
||||
func transformArgs(fs *funcScope, fun ast.Expr, args []ast.Expr) []ast.Expr {
|
||||
func transformArgs(fs *funcScope, fun ast.Expr, isBuiltin bool, args []ast.Expr) []ast.Expr {
|
||||
switch f := fun.(type) {
|
||||
case *ast.SelectorExpr:
|
||||
if f.Sel.Name == "FromAddress" {
|
||||
if f.Sel.Name == "FromAddress" || (isBuiltin && f.Sel.Name == "ToHash160") {
|
||||
return args[1:]
|
||||
}
|
||||
if fs != nil && isSyscall(fs) {
|
||||
|
@ -2178,7 +2181,7 @@ func (c *codegen) compile(info *buildInfo, pkg *packages.Package) error {
|
|||
}
|
||||
name := c.getFuncNameFromDecl(pkgPath, n)
|
||||
if !isInitFunc(n) && !isDeployFunc(n) && funUsage.funcUsed(name) &&
|
||||
(!isInteropPath(pkg.Path()) && !canInline(pkg.Path(), n.Name.Name)) {
|
||||
(!isInteropPath(pkg.Path()) && !canInline(pkg.Path(), n.Name.Name, false)) {
|
||||
c.convertFuncDecl(f, n, pkg)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package compiler_test
|
|||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -18,7 +17,6 @@ func checkCallCount(t *testing.T, src string, expectedCall, expectedInitSlot, ex
|
|||
|
||||
func checkInstrCount(t *testing.T, src string, expectedSSlotCount, expectedCall, expectedInitSlot, expectedLocalsMain int) {
|
||||
v, sp, _ := vmAndCompileInterop(t, src)
|
||||
v.PrintOps(os.Stdout)
|
||||
mainStart := -1
|
||||
for _, m := range sp.info.Methods {
|
||||
if m.Name.Name == "main" {
|
||||
|
|
|
@ -17,13 +17,17 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/base58"
|
||||
cinterop "github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/neotest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/neotest/chain"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/zaptest"
|
||||
)
|
||||
|
@ -116,6 +120,100 @@ func TestFromAddress(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAddressToHash160BuiltinConversion(t *testing.T) {
|
||||
a := "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN"
|
||||
h, err := address.StringToUint160(a)
|
||||
require.NoError(t, err)
|
||||
t.Run("builtin conversion", func(t *testing.T) {
|
||||
src := `package foo
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/lib/address"
|
||||
)
|
||||
var addr = address.ToHash160("` + a + `")
|
||||
func Main() interop.Hash160 {
|
||||
return addr
|
||||
}`
|
||||
prog := eval(t, src, h.BytesBE())
|
||||
// Address BE bytes expected to be present at program, which indicates that address conversion
|
||||
// was performed at compile-time.
|
||||
require.True(t, strings.Contains(string(prog), string(h.BytesBE())))
|
||||
// On the contrary, there should be no address string.
|
||||
require.False(t, strings.Contains(string(prog), a))
|
||||
})
|
||||
t.Run("generate code", func(t *testing.T) {
|
||||
src := `package foo
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/lib/address"
|
||||
)
|
||||
var addr = "` + a + `"
|
||||
func Main() interop.Hash160 {
|
||||
return address.ToHash160(addr)
|
||||
}`
|
||||
// Error on CALLT (std.Base58CheckDecode - method of StdLib native contract) is expected, which means
|
||||
// that address.ToHash160 code was honestly generated by the compiler without any optimisations.
|
||||
prog := evalWithError(t, src, "(CALLT): runtime error: invalid memory address or nil pointer dereference")
|
||||
// Address BE bytes expected not to be present at program, which indicates that address conversion
|
||||
// was not performed at compile-time.
|
||||
require.False(t, strings.Contains(string(prog), string(h.BytesBE())))
|
||||
// On the contrary, there should be an address string.
|
||||
require.True(t, strings.Contains(string(prog), a))
|
||||
})
|
||||
}
|
||||
|
||||
func TestInvokeAddressToFromHash160(t *testing.T) {
|
||||
a := "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN"
|
||||
h, err := address.StringToUint160(a)
|
||||
require.NoError(t, err)
|
||||
|
||||
bc, acc := chain.NewSingle(t)
|
||||
e := neotest.NewExecutor(t, bc, acc, acc)
|
||||
src := `package foo
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/lib/address"
|
||||
)
|
||||
const addr = "` + a + `"
|
||||
func ToHash160(a string) interop.Hash160 {
|
||||
return address.ToHash160(a)
|
||||
}
|
||||
func ToHash160AtCompileTime() interop.Hash160 {
|
||||
return address.ToHash160(addr)
|
||||
}
|
||||
func FromHash160(hash interop.Hash160) string {
|
||||
return address.FromHash160(hash)
|
||||
}`
|
||||
ctr := neotest.CompileSource(t, e.CommitteeHash, strings.NewReader(src), &compiler.Options{Name: "Helper"})
|
||||
e.DeployContract(t, ctr, nil)
|
||||
c := e.CommitteeInvoker(ctr.Hash)
|
||||
|
||||
t.Run("ToHash160", func(t *testing.T) {
|
||||
t.Run("invalid address length", func(t *testing.T) {
|
||||
c.InvokeFail(t, "invalid address length", "toHash160", base58.CheckEncode(make([]byte, util.Uint160Size+1+1)))
|
||||
})
|
||||
t.Run("invalid prefix", func(t *testing.T) {
|
||||
c.InvokeFail(t, "invalid address prefix", "toHash160", base58.CheckEncode(append([]byte{address.NEO2Prefix}, h.BytesBE()...)))
|
||||
})
|
||||
t.Run("good", func(t *testing.T) {
|
||||
c.Invoke(t, stackitem.NewBuffer(h.BytesBE()), "toHash160", a)
|
||||
})
|
||||
})
|
||||
t.Run("ToHash160Constant", func(t *testing.T) {
|
||||
t.Run("good", func(t *testing.T) {
|
||||
c.Invoke(t, stackitem.NewBuffer(h.BytesBE()), "toHash160AtCompileTime")
|
||||
})
|
||||
})
|
||||
t.Run("FromHash160", func(t *testing.T) {
|
||||
t.Run("good", func(t *testing.T) {
|
||||
c.Invoke(t, stackitem.NewByteArray([]byte(a)), "fromHash160", h.BytesBE())
|
||||
})
|
||||
t.Run("invalid length", func(t *testing.T) {
|
||||
c.InvokeFail(t, "invalid Hash160 length", "fromHash160", h.BytesBE()[:15])
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestAbort(t *testing.T) {
|
||||
src := `package foo
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/util"
|
||||
|
|
|
@ -56,6 +56,14 @@ func eval(t *testing.T, src string, result interface{}, expectedOps ...interface
|
|||
return script
|
||||
}
|
||||
|
||||
func evalWithError(t *testing.T, src string, e string) []byte {
|
||||
vm, _, prog := vmAndCompileInterop(t, src)
|
||||
err := vm.Run()
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), e), err)
|
||||
return prog
|
||||
}
|
||||
|
||||
func runAndCheck(t *testing.T, v *vm.VM, result interface{}) {
|
||||
err := v.Run()
|
||||
require.NoError(t, err)
|
||||
|
|
36
pkg/interop/lib/address/address.go
Normal file
36
pkg/interop/lib/address/address.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package address
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/native/std"
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
||||
)
|
||||
|
||||
// ToHash160 is a utility function that converts a Neo address to its hash
|
||||
// (160 bit BE value in a 20 byte slice). When parameter is known at compile time
|
||||
// (it's a constant string) the output is calculated by the compiler and this
|
||||
// function is optimized out completely. Otherwise, standard library and system
|
||||
// calls are used to perform the conversion and checks (panic will happen on
|
||||
// invalid input).
|
||||
func ToHash160(address string) interop.Hash160 {
|
||||
b := std.Base58CheckDecode([]byte(address))
|
||||
if len(b) != interop.Hash160Len+1 {
|
||||
panic("invalid address length")
|
||||
}
|
||||
if int(b[0]) != runtime.GetAddressVersion() {
|
||||
panic("invalid address prefix")
|
||||
}
|
||||
return b[1:21]
|
||||
}
|
||||
|
||||
// FromHash160 is a utility function that converts given Hash160 to
|
||||
// Base58-encoded Neo address.
|
||||
func FromHash160(hash interop.Hash160) string {
|
||||
if len(hash) != interop.Hash160Len {
|
||||
panic("invalid Hash160 length")
|
||||
}
|
||||
var res = make([]byte, interop.Hash160Len+1)
|
||||
res[0] = byte(runtime.GetAddressVersion())
|
||||
copy(res[1:], hash) // @fixme #2696
|
||||
return std.Base58CheckEncode(res)
|
||||
}
|
|
@ -18,6 +18,8 @@ func Abort() {
|
|||
// (160 bit BE value in a 20 byte slice). It can only be used for strings known
|
||||
// at compilation time, because the conversion is actually being done by the
|
||||
// compiler.
|
||||
//
|
||||
// Deprecated: use address.ToHash160 instead.
|
||||
func FromAddress(address string) interop.Hash160 {
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue