core,rpc: add NEP5 contract to testdata

Also transfer tokens between accounts.
This commit is contained in:
Evgenii Stratonikov 2020-03-05 12:28:46 +03:00
parent b945f4346a
commit 6d270c4550
5 changed files with 117 additions and 12 deletions

View file

@ -279,6 +279,7 @@ func TestCreateBasicChain(t *testing.T) {
// Push some contract into the chain.
avm, err := ioutil.ReadFile(prefix + "test_contract.avm")
require.NoError(t, err)
t.Logf("contractHash: %s", hash.Hash160(avm).StringLE())
var props smartcontract.PropertyState
script := io.NewBufBinWriter()
@ -352,6 +353,22 @@ func TestCreateBasicChain(t *testing.T) {
b = bc.newBlock(newMinerTX(), txNeo0to1)
require.NoError(t, bc.AddBlock(b))
sh := hash.Hash160(avm)
w := io.NewBufBinWriter()
emit.Int(w.BinWriter, 0)
emit.Opcode(w.BinWriter, opcode.NEWARRAY)
emit.String(w.BinWriter, "init")
emit.AppCall(w.BinWriter, sh, true)
initTx := transaction.NewInvocationTX(w.Bytes(), 0)
transferTx := newNEP5Transfer(sh, sh, priv0.GetScriptHash(), 1000)
b = bc.newBlock(newMinerTX(), initTx, transferTx)
require.NoError(t, bc.AddBlock(b))
transferTx = newNEP5Transfer(sh, priv0.GetScriptHash(), priv1.GetScriptHash(), 123)
b = bc.newBlock(newMinerTX(), transferTx)
require.NoError(t, bc.AddBlock(b))
if saveChain {
outStream, err := os.Create(prefix + "testblocks.acc")
require.NoError(t, err)
@ -375,3 +392,18 @@ func TestCreateBasicChain(t *testing.T) {
}
}
}
func newNEP5Transfer(sc, from, to util.Uint160, amount int64) *transaction.Transaction {
w := io.NewBufBinWriter()
emit.Int(w.BinWriter, amount)
emit.Bytes(w.BinWriter, to.BytesBE())
emit.Bytes(w.BinWriter, from.BytesBE())
emit.Int(w.BinWriter, 3)
emit.Opcode(w.BinWriter, opcode.PACK)
emit.String(w.BinWriter, "transfer")
emit.AppCall(w.BinWriter, sc, false)
emit.Opcode(w.BinWriter, opcode.THROWIFNOT)
script := w.Bytes()
return transaction.NewInvocationTX(script, 0)
}

View file

@ -44,14 +44,14 @@ var rpcTestCases = map[string][]rpcTestCase{
"getapplicationlog": {
{
name: "positive",
params: `["2441c2776cbab65bf81d38a839cf3a85689421631d4ba091be64703f02867315"]`,
params: `["440b84d1580e36e84379416b58d9a3ad978cc557e54fd7ec6a2648329975b333"]`,
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
check: func(t *testing.T, e *executor, acc interface{}) {
res, ok := acc.(*result.ApplicationLog)
require.True(t, ok)
expectedTxHash, err := util.Uint256DecodeStringLE("2441c2776cbab65bf81d38a839cf3a85689421631d4ba091be64703f02867315")
expectedTxHash, err := util.Uint256DecodeStringLE("cdb9fef85da4efde173682233b1a6166c9f39e8e41e40b75abb88230bf0c04bc")
require.NoError(t, err)
assert.Equal(t, expectedTxHash, res.TxHash)
assert.Equal(t, 1, len(res.Executions))
@ -117,13 +117,13 @@ var rpcTestCases = map[string][]rpcTestCase{
"getcontractstate": {
{
name: "positive",
params: `["1a696b32e239dd5eace3f025cac0a193a5746a27"]`,
params: `["d864728bdbc88da799bc43862ae6aaa62adc3a87"]`,
result: func(e *executor) interface{} { return &result.ContractState{} },
check: func(t *testing.T, e *executor, cs interface{}) {
res, ok := cs.(*result.ContractState)
require.True(t, ok)
assert.Equal(t, byte(0), res.Version)
assert.Equal(t, util.Uint160{0x1a, 0x69, 0x6b, 0x32, 0xe2, 0x39, 0xdd, 0x5e, 0xac, 0xe3, 0xf0, 0x25, 0xca, 0xc0, 0xa1, 0x93, 0xa5, 0x74, 0x6a, 0x27}, res.ScriptHash)
assert.Equal(t, util.Uint160{0xd8, 0x64, 0x72, 0x8b, 0xdb, 0xc8, 0x8d, 0xa7, 0x99, 0xbc, 0x43, 0x86, 0x2a, 0xe6, 0xaa, 0xa6, 0x2a, 0xdc, 0x3a, 0x87}, res.ScriptHash)
assert.Equal(t, "0.99", res.CodeVersion)
},
},
@ -146,7 +146,7 @@ var rpcTestCases = map[string][]rpcTestCase{
"getstorage": {
{
name: "positive",
params: `["1a696b32e239dd5eace3f025cac0a193a5746a27", "746573746b6579"]`,
params: `["d864728bdbc88da799bc43862ae6aaa62adc3a87", "746573746b6579"]`,
result: func(e *executor) interface{} {
v := hex.EncodeToString([]byte("testvalue"))
return &v
@ -154,7 +154,7 @@ var rpcTestCases = map[string][]rpcTestCase{
},
{
name: "missing key",
params: `["1a696b32e239dd5eace3f025cac0a193a5746a27", "7465"]`,
params: `["d864728bdbc88da799bc43862ae6aaa62adc3a87", "7465"]`,
result: func(e *executor) interface{} {
v := ""
return &v
@ -167,7 +167,7 @@ var rpcTestCases = map[string][]rpcTestCase{
},
{
name: "no second parameter",
params: `["1a696b32e239dd5eace3f025cac0a193a5746a27"]`,
params: `["d864728bdbc88da799bc43862ae6aaa62adc3a87"]`,
fail: true,
},
{
@ -177,7 +177,7 @@ var rpcTestCases = map[string][]rpcTestCase{
},
{
name: "invalid key",
params: `["1a696b32e239dd5eace3f025cac0a193a5746a27", "notahex"]`,
params: `["d864728bdbc88da799bc43862ae6aaa62adc3a87", "notahex"]`,
fail: true,
},
},

Binary file not shown.

View file

@ -1,9 +1,82 @@
package testdata
import "github.com/nspcc-dev/neo-go/pkg/interop/storage"
import (
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
"github.com/nspcc-dev/neo-go/pkg/interop/storage"
)
const (
totalSupply = 1000000
decimals = 2
)
func Main(operation string, args []interface{}) interface{} {
ctx := storage.GetContext()
storage.Put(ctx, args[0].([]byte), args[1].([]byte))
return true
runtime.Notify([]interface{}{"contract call", operation, args})
switch operation {
case "Put":
ctx := storage.GetContext()
storage.Put(ctx, args[0].([]byte), args[1].([]byte))
return true
case "totalSupply":
return totalSupply
case "decimals":
return decimals
case "name":
return "Rubl"
case "symbol":
return "RUB"
case "balanceOf":
ctx := storage.GetContext()
addr := args[0].([]byte)
if len(addr) != 20 {
runtime.Log("invalid address")
return false
}
amount := storage.Get(ctx, addr).(int)
runtime.Notify([]interface{}{"balanceOf", addr, amount})
return amount
case "transfer":
ctx := storage.GetContext()
from := args[0].([]byte)
if len(from) != 20 {
runtime.Log("invalid 'from' address")
return false
}
to := args[1].([]byte)
if len(to) != 20 {
runtime.Log("invalid 'to' address")
return false
}
amount := args[2].(int)
if amount < 0 {
runtime.Log("invalid amount")
return false
}
fromBalance := storage.Get(ctx, from).(int)
if fromBalance < amount {
runtime.Log("insufficient funds")
return false
}
fromBalance -= amount
storage.Put(ctx, from, fromBalance)
toBalance := storage.Get(ctx, to).(int)
toBalance += amount
storage.Put(ctx, to, toBalance)
runtime.Notify([]interface{}{"transfer", from, to, amount})
return true
case "init":
ctx := storage.GetContext()
h := engine.GetExecutingScriptHash()
amount := totalSupply
storage.Put(ctx, h, amount)
runtime.Notify([]interface{}{"transfer", []byte{}, h, amount})
return true
default:
panic("invalid operation")
}
}

Binary file not shown.