Merge pull request #1616 from nspcc-dev/fix/nativehash

native: fix contract hashes
This commit is contained in:
Roman Khimov 2020-12-15 13:18:47 +03:00 committed by GitHub
commit 7c2257803f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 43 additions and 29 deletions

Binary file not shown.

View file

@ -20,6 +20,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
"github.com/nspcc-dev/neo-go/pkg/core/native"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -555,7 +556,12 @@ func TestVerifyTx(t *testing.T) {
})
tx.Scripts = append(tx.Scripts, transaction.Witness{})
t.Run("NonZeroVerification", func(t *testing.T) {
tx.Scripts[len(tx.Scripts)-1].VerificationScript = bc.contracts.Oracle.Script
script, _ := state.CreateNativeContractHash(nativenames.Oracle)
w := io.NewBufBinWriter()
emit.Opcodes(w.BinWriter, opcode.ABORT)
emit.Bytes(w.BinWriter, util.Uint160{}.BytesBE())
emit.Bytes(w.BinWriter, script)
tx.Scripts[len(tx.Scripts)-1].VerificationScript = w.Bytes()
err := bc.VerifyTx(tx)
require.True(t, errors.Is(err, ErrNativeContractWitness), "got: %v", err)
})

View file

@ -8,18 +8,14 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
"github.com/nspcc-dev/neo-go/pkg/core/dao"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"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/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"go.uber.org/zap"
)
@ -114,12 +110,7 @@ func NewContractMD(name string) *ContractMD {
Methods: make(map[string]MethodAndPrice),
}
w := io.NewBufBinWriter()
emit.String(w.BinWriter, c.Name)
emit.Syscall(w.BinWriter, interopnames.SystemContractCallNative)
c.Script = w.Bytes()
c.Hash = hash.Hash160(c.Script)
c.Script, c.Hash = state.CreateNativeContractHash(c.Name)
c.Manifest = *manifest.DefaultManifest(name)
return c

View file

@ -0,0 +1,19 @@
package native
import (
"testing"
"github.com/stretchr/testify/require"
)
// Compatibility test. hashes are taken directly from C# node.
func TestNativeHashes(t *testing.T) {
require.Equal(t, "c0073f4c7069bf38995780c9da065f9b3949ea7a", newDesignate(false).Hash.StringLE())
require.Equal(t, "a6a6c15dcdc9b997dac448b6926522d22efeedfb", newGAS().Hash.StringLE())
require.Equal(t, "cd97b70d82d69adfcd9165374109419fade8d6ab", newManagement().Hash.StringLE())
require.Equal(t, "0a46e2e37c9987f570b4af253fb77e7eef0f72b6", newNEO().Hash.StringLE())
// Not yet a part of NEO.
//require.Equal(t, "", newNotary().Hash.StringLE()())
require.Equal(t, "b1c37d5847c2ae36bdde31d0cc833a7ad9667f8f", newOracle().Hash.StringLE())
require.Equal(t, "dde31084c0fdbebc7f5ed5f53a38905305ccee14", newPolicy().Hash.StringLE())
}

View file

@ -48,19 +48,11 @@ const (
oracleRequestPrice = 5000_0000
)
var (
oracleInvokeScript []byte
oracleScript []byte
)
var oracleScript []byte
func init() {
_, h := state.CreateNativeContractHash(nativenames.Oracle)
w := io.NewBufBinWriter()
emit.String(w.BinWriter, nativenames.Oracle)
emit.Syscall(w.BinWriter, interopnames.SystemContractCallNative)
oracleInvokeScript = w.Bytes()
h := hash.Hash160(oracleInvokeScript)
w = io.NewBufBinWriter()
emit.Int(w.BinWriter, 0)
emit.Opcodes(w.BinWriter, opcode.NEWARRAY)
emit.String(w.BinWriter, "finish")
@ -84,13 +76,6 @@ var (
ErrResponseNotFound = errors.New("oracle response not found")
)
// GetOracleInvokeScript returns oracle contract script.
func GetOracleInvokeScript() []byte {
b := make([]byte, len(oracleInvokeScript))
copy(b, oracleInvokeScript)
return b
}
// GetOracleResponseScript returns script for transaction with oracle response.
func GetOracleResponseScript() []byte {
b := make([]byte, len(oracleScript))

View file

@ -6,6 +6,7 @@ import (
"math"
"math/big"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
@ -114,3 +115,15 @@ func CreateContractHash(sender util.Uint160, script []byte) util.Uint160 {
}
return hash.Hash160(w.Bytes())
}
// CreateNativeContractHash returns script and hash for the native contract.
func CreateNativeContractHash(name string) ([]byte, util.Uint160) {
w := io.NewBufBinWriter()
emit.String(w.BinWriter, name)
emit.Syscall(w.BinWriter, interopnames.SystemContractCallNative)
if w.Err != nil {
panic(w.Err)
}
script := w.Bytes()
return script, CreateContractHash(util.Uint160{}, script)
}

View file

@ -57,7 +57,7 @@ type rpcTestCase struct {
}
const testContractHash = "743ed26f78e29ecd595535b74a943b1f9ccbc444"
const deploymentTxHash = "63605d1ba55b829b7816f2a2016e34b87296dcc824d069b2ee0aef1c1f5898dd"
const deploymentTxHash = "faa8d607f4000dbb3fc41dda51110369888b8b65c40de85d36ae9e4879dc4982"
const genesisBlockHash = "0542f4350c6e236d0509bcd98188b0034bfbecc1a0c7fcdb8e4295310d468b70"
const verifyContractHash = "a2eb22340979804cb10cc1add0b8822c201f4d8a"

Binary file not shown.