Merge pull request #1665 from nspcc-dev/nefstate
Store NEF in contract state
This commit is contained in:
commit
36b5751262
19 changed files with 172 additions and 78 deletions
|
@ -424,7 +424,7 @@ func importDeployed(ctx *cli.Context) error {
|
|||
return cli.NewExitError("contract has no `verify` method", 1)
|
||||
}
|
||||
acc.Address = address.Uint160ToString(cs.Hash)
|
||||
acc.Contract.Script = cs.Script
|
||||
acc.Contract.Script = cs.NEF.Script
|
||||
acc.Contract.Parameters = acc.Contract.Parameters[:0]
|
||||
for _, p := range md.Parameters {
|
||||
acc.Contract.Parameters = append(acc.Contract.Parameters, wallet.ContractParam{
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
cinterop "github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"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"
|
||||
|
@ -162,15 +163,19 @@ func TestAppCall(t *testing.T) {
|
|||
ih := hash.Hash160(inner)
|
||||
var contractGetter = func(_ dao.DAO, h util.Uint160) (*state.Contract, error) {
|
||||
if h.Equals(ih) {
|
||||
innerNef, err := nef.NewFile(inner)
|
||||
require.NoError(t, err)
|
||||
return &state.Contract{
|
||||
Hash: ih,
|
||||
Script: inner,
|
||||
NEF: *innerNef,
|
||||
Manifest: *m,
|
||||
}, nil
|
||||
} else if h.Equals(barH) {
|
||||
barNef, err := nef.NewFile(barCtr)
|
||||
require.NoError(t, err)
|
||||
return &state.Contract{
|
||||
Hash: barH,
|
||||
Script: barCtr,
|
||||
NEF: *barNef,
|
||||
Manifest: *mBar,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -1670,7 +1670,7 @@ func (bc *Blockchain) initVerificationVM(ic *interop.Context, hash util.Uint160,
|
|||
return ErrInvalidVerificationContract
|
||||
}
|
||||
initMD := cs.Manifest.ABI.GetMethod(manifest.MethodInit)
|
||||
v.LoadScriptWithHash(cs.Script, hash, smartcontract.ReadStates)
|
||||
v.LoadScriptWithHash(cs.NEF.Script, hash, smartcontract.ReadStates)
|
||||
v.Jump(v.Context(), md.Offset)
|
||||
|
||||
if cs.ID <= 0 {
|
||||
|
|
|
@ -418,7 +418,7 @@ func addNetworkFee(bc *Blockchain, tx *transaction.Transaction, sender *wallet.A
|
|||
for _, cosigner := range tx.Signers {
|
||||
contract := bc.GetContractState(cosigner.Account)
|
||||
if contract != nil {
|
||||
netFee, sizeDelta = fee.Calculate(bc.GetBaseExecFee(), contract.Script)
|
||||
netFee, sizeDelta = fee.Calculate(bc.GetBaseExecFee(), contract.NEF.Script)
|
||||
tx.NetworkFee += netFee
|
||||
size += sizeDelta
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto"
|
||||
"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/nef"
|
||||
"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"
|
||||
|
@ -103,7 +104,7 @@ type ContractMD struct {
|
|||
Manifest manifest.Manifest
|
||||
Name string
|
||||
ContractID int32
|
||||
Script []byte
|
||||
NEF nef.File
|
||||
Hash util.Uint160
|
||||
Methods map[string]MethodAndPrice
|
||||
}
|
||||
|
@ -115,7 +116,13 @@ func NewContractMD(name string) *ContractMD {
|
|||
Methods: make(map[string]MethodAndPrice),
|
||||
}
|
||||
|
||||
c.Script, c.Hash = state.CreateNativeContractHash(c.Name)
|
||||
// NEF is now stored in contract state and affects state dump.
|
||||
// Therefore values are taken from C# node.
|
||||
c.NEF.Header.Compiler = "ScriptBuilder"
|
||||
c.NEF.Header.Magic = nef.Magic
|
||||
c.NEF.Header.Version = "3.0"
|
||||
c.NEF.Script, c.Hash = state.CreateNativeContractHash(c.Name)
|
||||
c.NEF.Checksum = c.NEF.CalculateChecksum()
|
||||
c.Manifest = *manifest.DefaultManifest(name)
|
||||
|
||||
return c
|
||||
|
|
|
@ -82,7 +82,7 @@ func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contra
|
|||
}
|
||||
|
||||
ic.VM.Invocations[cs.Hash]++
|
||||
ic.VM.LoadScriptWithCallingHash(caller, cs.Script, cs.Hash, ic.VM.Context().GetCallFlags()&f)
|
||||
ic.VM.LoadScriptWithCallingHash(caller, cs.NEF.Script, cs.Hash, ic.VM.Context().GetCallFlags()&f)
|
||||
var isNative bool
|
||||
for i := range ic.Natives {
|
||||
if ic.Natives[i].Metadata().Hash.Equals(cs.Hash) {
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"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"
|
||||
|
@ -160,8 +161,10 @@ func createVMAndPushTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop
|
|||
func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.Context, *Blockchain) {
|
||||
script := []byte("testscript")
|
||||
m := manifest.NewManifest("Test")
|
||||
ne, err := nef.NewFile(script)
|
||||
require.NoError(t, err)
|
||||
contractState := &state.Contract{
|
||||
Script: script,
|
||||
NEF: *ne,
|
||||
Hash: hash.Hash160(script),
|
||||
Manifest: *m,
|
||||
ID: 123,
|
||||
|
|
|
@ -338,7 +338,7 @@ func contractIsStandard(ic *interop.Context) error {
|
|||
var result bool
|
||||
cs, _ := ic.GetContract(u)
|
||||
if cs != nil {
|
||||
result = vm.IsStandardContract(cs.Script)
|
||||
result = vm.IsStandardContract(cs.NEF.Script)
|
||||
} else {
|
||||
if tx, ok := ic.Container.(*transaction.Transaction); ok {
|
||||
for _, witness := range tx.Scripts {
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"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/nef"
|
||||
"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"
|
||||
|
@ -226,7 +227,9 @@ func TestContractIsStandard(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
pub := priv.PublicKey()
|
||||
err = chain.contracts.Management.PutContractState(ic.DAO, &state.Contract{ID: 42, Hash: pub.GetScriptHash(), Script: pub.GetVerificationScript()})
|
||||
ne, err := nef.NewFile(pub.GetVerificationScript())
|
||||
require.NoError(t, err)
|
||||
err = chain.contracts.Management.PutContractState(ic.DAO, &state.Contract{ID: 42, Hash: pub.GetScriptHash(), NEF: *ne})
|
||||
require.NoError(t, err)
|
||||
|
||||
v.Estack().PushVal(pub.GetScriptHash().BytesBE())
|
||||
|
@ -235,7 +238,9 @@ func TestContractIsStandard(t *testing.T) {
|
|||
})
|
||||
t.Run("contract stored, false", func(t *testing.T) {
|
||||
script := []byte{byte(opcode.PUSHT)}
|
||||
require.NoError(t, chain.contracts.Management.PutContractState(ic.DAO, &state.Contract{ID: 24, Hash: hash.Hash160(script), Script: script}))
|
||||
ne, err := nef.NewFile(script)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, chain.contracts.Management.PutContractState(ic.DAO, &state.Contract{ID: 24, Hash: hash.Hash160(script), NEF: *ne}))
|
||||
|
||||
v.Estack().PushVal(crypto.Hash160(script).BytesBE())
|
||||
require.NoError(t, contractIsStandard(ic))
|
||||
|
@ -343,7 +348,7 @@ func TestStoragePut(t *testing.T) {
|
|||
|
||||
initVM := func(t *testing.T, key, value []byte, gas int64) {
|
||||
v := ic.SpawnVM()
|
||||
v.LoadScript(cs.Script)
|
||||
v.LoadScript(cs.NEF.Script)
|
||||
v.GasLimit = gas
|
||||
v.Estack().PushVal(value)
|
||||
v.Estack().PushVal(key)
|
||||
|
@ -392,7 +397,7 @@ func TestStoragePut(t *testing.T) {
|
|||
})
|
||||
t.Run("item exists and is const", func(t *testing.T) {
|
||||
v := ic.SpawnVM()
|
||||
v.LoadScript(cs.Script)
|
||||
v.LoadScript(cs.NEF.Script)
|
||||
v.GasLimit = -1
|
||||
v.Estack().PushVal(1)
|
||||
v.Estack().PushVal("value")
|
||||
|
@ -413,7 +418,7 @@ func TestStorageDelete(t *testing.T) {
|
|||
defer bc.Close()
|
||||
|
||||
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, cs))
|
||||
v.LoadScriptWithHash(cs.Script, cs.Hash, smartcontract.All)
|
||||
v.LoadScriptWithHash(cs.NEF.Script, cs.Hash, smartcontract.All)
|
||||
put := func(key, value string, flag int) {
|
||||
v.Estack().PushVal(flag)
|
||||
v.Estack().PushVal(value)
|
||||
|
@ -615,11 +620,15 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
|
|||
},
|
||||
}
|
||||
cs := &state.Contract{
|
||||
Script: script,
|
||||
Hash: h,
|
||||
Manifest: *m,
|
||||
ID: 42,
|
||||
}
|
||||
ne, err := nef.NewFile(script)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cs.NEF = *ne
|
||||
|
||||
currScript := []byte{byte(opcode.RET)}
|
||||
m = manifest.NewManifest("TestAux")
|
||||
|
@ -631,9 +640,13 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
|
|||
perm.Methods.Add("justReturn")
|
||||
perm.Methods.Add("getValue")
|
||||
m.Permissions = append(m.Permissions, *perm)
|
||||
ne, err = nef.NewFile(currScript)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return cs, &state.Contract{
|
||||
Script: currScript,
|
||||
NEF: *ne,
|
||||
Hash: hash.Hash160(currScript),
|
||||
Manifest: *m,
|
||||
ID: 123,
|
||||
|
@ -666,8 +679,8 @@ func TestContractCall(t *testing.T) {
|
|||
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, cs))
|
||||
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, currCs))
|
||||
|
||||
currScript := currCs.Script
|
||||
h := hash.Hash160(cs.Script)
|
||||
currScript := currCs.NEF.Script
|
||||
h := hash.Hash160(cs.NEF.Script)
|
||||
|
||||
addArgs := stackitem.NewArray([]stackitem.Item{stackitem.Make(1), stackitem.Make(2)})
|
||||
t.Run("Good", func(t *testing.T) {
|
||||
|
@ -823,7 +836,7 @@ func TestMethodCallback(t *testing.T) {
|
|||
t.Run("Invalid", func(t *testing.T) {
|
||||
runInvalid := func(args ...interface{}) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
loadScript(ic, currCs.Script, 42)
|
||||
loadScript(ic, currCs.NEF.Script, 42)
|
||||
for i := range args {
|
||||
ic.VM.Estack().PushVal(args[i])
|
||||
}
|
||||
|
@ -836,7 +849,7 @@ func TestMethodCallback(t *testing.T) {
|
|||
t.Run("DisallowedMethod", runInvalid("ret7", rawHash))
|
||||
t.Run("Initialize", runInvalid("_initialize", rawHash))
|
||||
t.Run("NotEnoughArguments", func(t *testing.T) {
|
||||
loadScript(ic, currCs.Script, 42, "add", rawHash)
|
||||
loadScript(ic, currCs.NEF.Script, 42, "add", rawHash)
|
||||
require.NoError(t, callback.CreateFromMethod(ic))
|
||||
|
||||
ic.VM.Estack().InsertAt(vm.NewElement(stackitem.NewArray([]stackitem.Item{stackitem.Make(1)})), 1)
|
||||
|
@ -844,7 +857,7 @@ func TestMethodCallback(t *testing.T) {
|
|||
})
|
||||
t.Run("CallIsNotAllowed", func(t *testing.T) {
|
||||
ic.SpawnVM()
|
||||
ic.VM.Load(currCs.Script)
|
||||
ic.VM.Load(currCs.NEF.Script)
|
||||
ic.VM.Estack().PushVal("add")
|
||||
ic.VM.Estack().PushVal(rawHash)
|
||||
require.NoError(t, callback.CreateFromMethod(ic))
|
||||
|
@ -856,7 +869,7 @@ func TestMethodCallback(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Good", func(t *testing.T) {
|
||||
loadScript(ic, currCs.Script, 42, "add", rawHash)
|
||||
loadScript(ic, currCs.NEF.Script, 42, "add", rawHash)
|
||||
require.NoError(t, callback.CreateFromMethod(ic))
|
||||
|
||||
args := stackitem.NewArray([]stackitem.Item{stackitem.Make(1), stackitem.Make(5)})
|
||||
|
@ -1074,10 +1087,12 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
}
|
||||
contractScript := []byte{byte(opcode.PUSH1), byte(opcode.RET)}
|
||||
contractScriptHash := hash.Hash160(contractScript)
|
||||
ne, err := nef.NewFile(contractScript)
|
||||
require.NoError(t, err)
|
||||
contractState := &state.Contract{
|
||||
ID: 15,
|
||||
Hash: contractScriptHash,
|
||||
Script: contractScript,
|
||||
ID: 15,
|
||||
Hash: contractScriptHash,
|
||||
NEF: *ne,
|
||||
Manifest: manifest.Manifest{
|
||||
Groups: []manifest.Group{{PublicKey: pk.PublicKey()}},
|
||||
},
|
||||
|
|
|
@ -252,7 +252,7 @@ func (m *Management) Deploy(d dao.DAO, sender util.Uint160, neff *nef.File, mani
|
|||
newcontract := &state.Contract{
|
||||
ID: id,
|
||||
Hash: h,
|
||||
Script: neff.Script,
|
||||
NEF: *neff,
|
||||
Manifest: *manif,
|
||||
}
|
||||
err = m.PutContractState(d, newcontract)
|
||||
|
@ -292,7 +292,7 @@ func (m *Management) Update(d dao.DAO, hash util.Uint160, neff *nef.File, manif
|
|||
// if NEF was provided, update the contract script
|
||||
if neff != nil {
|
||||
m.markUpdated(hash)
|
||||
contract.Script = neff.Script
|
||||
contract.NEF = *neff
|
||||
}
|
||||
// if manifest was provided, update the contract manifest
|
||||
if manif != nil {
|
||||
|
@ -415,7 +415,7 @@ func (m *Management) OnPersist(ic *interop.Context) error {
|
|||
cs := &state.Contract{
|
||||
ID: md.ContractID,
|
||||
Hash: md.Hash,
|
||||
Script: md.Script,
|
||||
NEF: md.NEF,
|
||||
Manifest: md.Manifest,
|
||||
}
|
||||
err := m.PutContractState(ic.DAO, cs)
|
||||
|
|
|
@ -30,7 +30,7 @@ func TestDeployGetUpdateDestroyContract(t *testing.T) {
|
|||
require.Equal(t, int32(1), contract.ID)
|
||||
require.Equal(t, uint16(0), contract.UpdateCounter)
|
||||
require.Equal(t, h, contract.Hash)
|
||||
require.Equal(t, script, contract.Script)
|
||||
require.Equal(t, ne, &contract.NEF)
|
||||
require.Equal(t, *manif, contract.Manifest)
|
||||
|
||||
// Double deploy.
|
||||
|
@ -44,7 +44,7 @@ func TestDeployGetUpdateDestroyContract(t *testing.T) {
|
|||
require.Equal(t, int32(2), contract2.ID)
|
||||
require.Equal(t, uint16(0), contract2.UpdateCounter)
|
||||
require.Equal(t, state.CreateContractHash(sender2, script), contract2.Hash)
|
||||
require.Equal(t, script, contract2.Script)
|
||||
require.Equal(t, ne, &contract2.NEF)
|
||||
require.Equal(t, *manif, contract2.Manifest)
|
||||
|
||||
refContract, err := mgmt.GetContract(d, h)
|
||||
|
|
|
@ -172,7 +172,7 @@ func TestNativeContract_Invoke(t *testing.T) {
|
|||
|
||||
err := chain.contracts.Management.PutContractState(chain.dao, &state.Contract{
|
||||
ID: 1,
|
||||
Script: tn.meta.Script,
|
||||
NEF: tn.meta.NEF,
|
||||
Hash: tn.meta.Hash,
|
||||
Manifest: tn.meta.Manifest,
|
||||
})
|
||||
|
@ -210,7 +210,7 @@ func TestNativeContract_InvokeInternal(t *testing.T) {
|
|||
|
||||
err := chain.contracts.Management.PutContractState(chain.dao, &state.Contract{
|
||||
ID: 1,
|
||||
Script: tn.meta.Script,
|
||||
NEF: tn.meta.NEF,
|
||||
Manifest: tn.meta.Manifest,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
@ -252,7 +252,7 @@ func TestNativeContract_InvokeOtherContract(t *testing.T) {
|
|||
err := chain.contracts.Management.PutContractState(chain.dao, &state.Contract{
|
||||
ID: 1,
|
||||
Hash: tn.meta.Hash,
|
||||
Script: tn.meta.Script,
|
||||
NEF: tn.meta.NEF,
|
||||
Manifest: tn.meta.Manifest,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -36,10 +36,10 @@ func TestRestoreAfterDeploy(t *testing.T) {
|
|||
mgmtHash := bc.ManagementContractHash()
|
||||
cs1, _ := getTestContractState(bc)
|
||||
cs1.ID = 1
|
||||
cs1.Hash = state.CreateContractHash(testchain.MultisigScriptHash(), cs1.Script)
|
||||
cs1.Hash = state.CreateContractHash(testchain.MultisigScriptHash(), cs1.NEF.Script)
|
||||
manif1, err := json.Marshal(cs1.Manifest)
|
||||
require.NoError(t, err)
|
||||
nef1, err := nef.NewFile(cs1.Script)
|
||||
nef1, err := nef.NewFile(cs1.NEF.Script)
|
||||
require.NoError(t, err)
|
||||
nef1b, err := nef1.Bytes()
|
||||
require.NoError(t, err)
|
||||
|
@ -80,10 +80,10 @@ func TestContractDeploy(t *testing.T) {
|
|||
mgmtHash := bc.ManagementContractHash()
|
||||
cs1, _ := getTestContractState(bc)
|
||||
cs1.ID = 1
|
||||
cs1.Hash = state.CreateContractHash(testchain.MultisigScriptHash(), cs1.Script)
|
||||
cs1.Hash = state.CreateContractHash(testchain.MultisigScriptHash(), cs1.NEF.Script)
|
||||
manif1, err := json.Marshal(cs1.Manifest)
|
||||
require.NoError(t, err)
|
||||
nef1, err := nef.NewFile(cs1.Script)
|
||||
nef1, err := nef.NewFile(cs1.NEF.Script)
|
||||
require.NoError(t, err)
|
||||
nef1b, err := nef1.Bytes()
|
||||
require.NoError(t, err)
|
||||
|
@ -278,7 +278,7 @@ func TestContractUpdate(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
manif1, err := json.Marshal(cs1.Manifest)
|
||||
require.NoError(t, err)
|
||||
nef1, err := nef.NewFile(cs1.Script)
|
||||
nef1, err := nef.NewFile(cs1.NEF.Script)
|
||||
require.NoError(t, err)
|
||||
nef1b, err := nef1.Bytes()
|
||||
require.NoError(t, err)
|
||||
|
@ -322,10 +322,9 @@ func TestContractUpdate(t *testing.T) {
|
|||
checkFAULTState(t, res)
|
||||
})
|
||||
|
||||
cs1.Script = append(cs1.Script, byte(opcode.RET))
|
||||
nef1, err = nef.NewFile(cs1.Script)
|
||||
require.NoError(t, err)
|
||||
nef1b, err = nef1.Bytes()
|
||||
cs1.NEF.Script = append(cs1.NEF.Script, byte(opcode.RET))
|
||||
cs1.NEF.Checksum = cs1.NEF.CalculateChecksum()
|
||||
nef1b, err = cs1.NEF.Bytes()
|
||||
require.NoError(t, err)
|
||||
cs1.UpdateCounter++
|
||||
|
||||
|
@ -376,10 +375,9 @@ func TestContractUpdate(t *testing.T) {
|
|||
})
|
||||
})
|
||||
|
||||
cs1.Script = append(cs1.Script, byte(opcode.ABORT))
|
||||
nef1, err = nef.NewFile(cs1.Script)
|
||||
require.NoError(t, err)
|
||||
nef1b, err = nef1.Bytes()
|
||||
cs1.NEF.Script = append(cs1.NEF.Script, byte(opcode.ABORT))
|
||||
cs1.NEF.Checksum = cs1.NEF.CalculateChecksum()
|
||||
nef1b, err = cs1.NEF.Bytes()
|
||||
require.NoError(t, err)
|
||||
cs1.Manifest.Extra = "update me once more"
|
||||
manif1, err = json.Marshal(cs1.Manifest)
|
||||
|
@ -471,12 +469,14 @@ func compareContractStates(t *testing.T, expected *state.Contract, actual stacki
|
|||
|
||||
expectedManifest, err := json.Marshal(expected.Manifest)
|
||||
require.NoError(t, err)
|
||||
expectedNef, err := expected.NEF.Bytes()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 5, len(act))
|
||||
require.Equal(t, expected.ID, int32(act[0].Value().(*big.Int).Int64()))
|
||||
require.Equal(t, expected.UpdateCounter, uint16(act[1].Value().(*big.Int).Int64()))
|
||||
require.Equal(t, expected.Hash.BytesBE(), act[2].Value().([]byte))
|
||||
require.Equal(t, expected.Script, act[3].Value().([]byte))
|
||||
require.Equal(t, expectedNef, act[3].Value().([]byte))
|
||||
require.Equal(t, expectedManifest, act[4].Value().([]byte))
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"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/nef"
|
||||
"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"
|
||||
|
@ -83,8 +84,12 @@ func getOracleContractState(h util.Uint160) *state.Contract {
|
|||
m.Permissions = append(m.Permissions, *perm)
|
||||
|
||||
script := w.Bytes()
|
||||
ne, err := nef.NewFile(script)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &state.Contract{
|
||||
Script: script,
|
||||
NEF: *ne,
|
||||
Hash: hash.Hash160(script),
|
||||
Manifest: *m,
|
||||
ID: 42,
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"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"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
|
@ -21,7 +22,7 @@ type Contract struct {
|
|||
ID int32 `json:"id"`
|
||||
UpdateCounter uint16 `json:"updatecounter"`
|
||||
Hash util.Uint160 `json:"hash"`
|
||||
Script []byte `json:"script"`
|
||||
NEF nef.File `json:"nef"`
|
||||
Manifest manifest.Manifest `json:"manifest"`
|
||||
}
|
||||
|
||||
|
@ -50,11 +51,15 @@ func (c *Contract) ToStackItem() (stackitem.Item, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rawNef, err := c.NEF.Bytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return stackitem.NewArray([]stackitem.Item{
|
||||
stackitem.Make(c.ID),
|
||||
stackitem.Make(c.UpdateCounter),
|
||||
stackitem.NewByteArray(c.Hash.BytesBE()),
|
||||
stackitem.NewByteArray(c.Script),
|
||||
stackitem.NewByteArray(rawNef),
|
||||
stackitem.NewByteArray(manifest),
|
||||
}), nil
|
||||
}
|
||||
|
@ -94,8 +99,10 @@ func (c *Contract) FromStackItem(item stackitem.Item) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Script = make([]byte, len(bytes))
|
||||
copy(c.Script, bytes)
|
||||
c.NEF, err = nef.FileFromBytes(bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bytes, err = arr[4].TryBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"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/nef"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -37,9 +38,18 @@ func TestEncodeDecodeContractState(t *testing.T) {
|
|||
ID: 123,
|
||||
UpdateCounter: 42,
|
||||
Hash: h,
|
||||
Script: script,
|
||||
Manifest: *m,
|
||||
NEF: nef.File{
|
||||
Header: nef.Header{
|
||||
Magic: nef.Magic,
|
||||
Compiler: "neo-go.test",
|
||||
Version: "test",
|
||||
},
|
||||
Script: script,
|
||||
Checksum: 0,
|
||||
},
|
||||
Manifest: *m,
|
||||
}
|
||||
contract.NEF.Checksum = contract.NEF.CalculateChecksum()
|
||||
|
||||
t.Run("Serializable", func(t *testing.T) {
|
||||
contractDecoded := new(Contract)
|
||||
|
@ -67,7 +77,10 @@ func TestContractFromStackItem(t *testing.T) {
|
|||
id = stackitem.Make(42)
|
||||
counter = stackitem.Make(11)
|
||||
chash = stackitem.Make(util.Uint160{1, 2, 3}.BytesBE())
|
||||
script = stackitem.Make([]byte{0, 9, 8})
|
||||
script = []byte{0, 9, 8}
|
||||
nefFile, _ = nef.NewFile(script)
|
||||
rawNef, _ = nefFile.Bytes()
|
||||
nefItem = stackitem.NewByteArray(rawNef)
|
||||
manifest = manifest.DefaultManifest("stack item")
|
||||
manifestB, _ = json.Marshal(manifest)
|
||||
manifItem = stackitem.Make(manifestB)
|
||||
|
@ -77,15 +90,15 @@ func TestContractFromStackItem(t *testing.T) {
|
|||
item stackitem.Item
|
||||
}{
|
||||
{"not an array", stackitem.Make(1)},
|
||||
{"id is not a number", stackitem.Make([]stackitem.Item{manifItem, counter, chash, script, manifItem})},
|
||||
{"id is out of range", stackitem.Make([]stackitem.Item{stackitem.Make(math.MaxUint32), counter, chash, script, manifItem})},
|
||||
{"counter is not a number", stackitem.Make([]stackitem.Item{id, manifItem, chash, script, manifItem})},
|
||||
{"counter is out of range", stackitem.Make([]stackitem.Item{id, stackitem.Make(100500), chash, script, manifItem})},
|
||||
{"hash is not a byte string", stackitem.Make([]stackitem.Item{id, counter, stackitem.NewArray(nil), script, manifItem})},
|
||||
{"hash is not a hash", stackitem.Make([]stackitem.Item{id, counter, stackitem.Make([]byte{1, 2, 3}), script, manifItem})},
|
||||
{"script is not a byte string", stackitem.Make([]stackitem.Item{id, counter, chash, stackitem.NewArray(nil), manifItem})},
|
||||
{"manifest is not a byte string", stackitem.Make([]stackitem.Item{id, counter, chash, script, stackitem.NewArray(nil)})},
|
||||
{"manifest is not correct", stackitem.Make([]stackitem.Item{id, counter, chash, script, stackitem.Make(100500)})},
|
||||
{"id is not a number", stackitem.Make([]stackitem.Item{manifItem, counter, chash, nefItem, manifItem})},
|
||||
{"id is out of range", stackitem.Make([]stackitem.Item{stackitem.Make(math.MaxUint32), counter, chash, nefItem, manifItem})},
|
||||
{"counter is not a number", stackitem.Make([]stackitem.Item{id, manifItem, chash, nefItem, manifItem})},
|
||||
{"counter is out of range", stackitem.Make([]stackitem.Item{id, stackitem.Make(100500), chash, nefItem, manifItem})},
|
||||
{"hash is not a byte string", stackitem.Make([]stackitem.Item{id, counter, stackitem.NewArray(nil), nefItem, manifItem})},
|
||||
{"hash is not a hash", stackitem.Make([]stackitem.Item{id, counter, stackitem.Make([]byte{1, 2, 3}), nefItem, manifItem})},
|
||||
{"nef is not a byte string", stackitem.Make([]stackitem.Item{id, counter, chash, stackitem.NewArray(nil), manifItem})},
|
||||
{"manifest is not a byte string", stackitem.Make([]stackitem.Item{id, counter, chash, nefItem, stackitem.NewArray(nil)})},
|
||||
{"manifest is not correct", stackitem.Make([]stackitem.Item{id, counter, chash, nefItem, stackitem.Make(100500)})},
|
||||
}
|
||||
)
|
||||
for _, cs := range badCases {
|
||||
|
@ -96,6 +109,6 @@ func TestContractFromStackItem(t *testing.T) {
|
|||
})
|
||||
}
|
||||
var c = new(Contract)
|
||||
err := c.FromStackItem(stackitem.Make([]stackitem.Item{id, counter, chash, script, manifItem}))
|
||||
err := c.FromStackItem(stackitem.Make([]stackitem.Item{id, counter, chash, nefItem, manifItem}))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||
"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/nef"
|
||||
"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"
|
||||
|
@ -329,7 +330,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
}
|
||||
return c.GetContractStateByHash(hash)
|
||||
},
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","manifest":{"name":"Test","abi":{"methods":[],"events":[]},"groups":[],"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"nef":{"magic":860243278,"compiler":"neo-go","version":"3.0","script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","checksum":749050685},"manifest":{"name":"Test","abi":{"methods":[],"events":[]},"groups":[],"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
||||
if err != nil {
|
||||
|
@ -339,7 +340,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
cs := &state.Contract{
|
||||
ID: 0,
|
||||
Hash: hash.Hash160(script),
|
||||
Script: script,
|
||||
NEF: newTestNEF(script),
|
||||
Manifest: *m,
|
||||
}
|
||||
return cs
|
||||
|
@ -350,7 +351,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.GetContractStateByAddressOrName("NWiu5oejTu925aeL9Hc1LX8SvaJhE23h15")
|
||||
},
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","manifest":{"name":"Test","abi":{"methods":[],"events":[]},"groups":[],"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"nef":{"magic":860243278,"compiler":"neo-go","version":"3.0","script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","checksum":749050685},"manifest":{"name":"Test","abi":{"methods":[],"events":[]},"groups":[],"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
||||
if err != nil {
|
||||
|
@ -360,7 +361,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
cs := &state.Contract{
|
||||
ID: 0,
|
||||
Hash: hash.Hash160(script),
|
||||
Script: script,
|
||||
NEF: newTestNEF(script),
|
||||
Manifest: *m,
|
||||
}
|
||||
return cs
|
||||
|
@ -371,7 +372,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.GetContractStateByID(0)
|
||||
},
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","manifest":{"name":"Test","abi":{"methods":[],"events":[]},"groups":[],"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"nef":{"magic":860243278,"compiler":"neo-go","version":"3.0","script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","checksum":749050685},"manifest":{"name":"Test","abi":{"methods":[],"events":[]},"groups":[],"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
||||
if err != nil {
|
||||
|
@ -381,7 +382,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
cs := &state.Contract{
|
||||
ID: 0,
|
||||
Hash: hash.Hash160(script),
|
||||
Script: script,
|
||||
NEF: newTestNEF(script),
|
||||
Manifest: *m,
|
||||
}
|
||||
return cs
|
||||
|
@ -1627,3 +1628,13 @@ func TestUninitedClient(t *testing.T) {
|
|||
_, err = c.GetFeePerByte()
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func newTestNEF(script []byte) nef.File {
|
||||
var ne nef.File
|
||||
ne.Header.Magic = nef.Magic
|
||||
ne.Header.Version = "3.0"
|
||||
ne.Header.Compiler = "neo-go"
|
||||
ne.Script = script
|
||||
ne.Checksum = ne.CalculateChecksum()
|
||||
return ne
|
||||
}
|
||||
|
|
|
@ -36,16 +36,16 @@ const (
|
|||
|
||||
// File represents compiled contract file structure according to the NEF3 standard.
|
||||
type File struct {
|
||||
Header Header
|
||||
Script []byte
|
||||
Checksum uint32
|
||||
Header
|
||||
Script []byte `json:"script"`
|
||||
Checksum uint32 `json:"checksum"`
|
||||
}
|
||||
|
||||
// Header represents File header.
|
||||
type Header struct {
|
||||
Magic uint32
|
||||
Compiler string
|
||||
Version string
|
||||
Magic uint32 `json:"magic"`
|
||||
Compiler string `json:"compiler"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
// NewFile returns new NEF3 file with script specified.
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package nef
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
||||
|
@ -74,3 +77,28 @@ func TestBytesFromBytes(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestMarshalUnmarshalJSON(t *testing.T) {
|
||||
expected := &File{
|
||||
Header: Header{
|
||||
Magic: Magic,
|
||||
Compiler: "test.compiler",
|
||||
Version: "test.ver",
|
||||
},
|
||||
Script: []byte{1, 2, 3, 4},
|
||||
}
|
||||
expected.Checksum = expected.CalculateChecksum()
|
||||
|
||||
data, err := json.Marshal(expected)
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, `{
|
||||
"magic":`+strconv.FormatUint(uint64(Magic), 10)+`,
|
||||
"compiler": "test.compiler",
|
||||
"version": "test.ver",
|
||||
"script": "`+base64.StdEncoding.EncodeToString(expected.Script)+`",
|
||||
"checksum":`+strconv.FormatUint(uint64(expected.Checksum), 10)+`}`, string(data))
|
||||
|
||||
actual := new(File)
|
||||
require.NoError(t, json.Unmarshal(data, actual))
|
||||
require.Equal(t, expected, actual)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue