package bytecode import ( "encoding/hex" "testing" "github.com/stretchr/testify/require" ) func fromHexadecimalStringToBytes(str string) []byte { data, _ := hex.DecodeString(str) return data } type ExtractCallTest struct { name string script string bytecodeStr string expected []SyscallParameters wantErr bool } var tests = []ExtractCallTest{ { name: "valid bytecode 1", script: "PUSHINT16 3600\n" + "PUSHINT32 315360000\n" + "PUSHINT16 600\n" + "PUSHINT16 3600\n" + "PUSHDATA1 6f70734066726f737466732e696e666f\n" + "PUSHDATA1 0x56c989e76f9a2ca05bb5caa6c96f524d905accd8\n" + "PUSHDATA1 frostfs\n" + "PUSH7\n" + "PACK\n" + "PUSH15\n" + "PUSHDATA1 register\n" + "PUSHDATA1 0x76c10d0295b7e76a5674c55d702f04ce280e745e\n" + "SYSCALL System.Contract.Call\n" + "ASSERT", bytecodeStr: "0c106f70734066726f737466" + "732e696e666f0c14d8cc5a90" + "4d526fc9a6cab55ba02c9a6f" + "e789c9560c0766726f737466" + "7317c01f0c08726567697374" + "65720c145e740e28ce042f70" + "5dc574566ae7b795020dc176" + "41627d5b5239", expected: []SyscallParameters{ { Contract: "NUXPjTBsLY6fgVPfmBf8uLk9QBVqgKKkdB", Method: "register", }, }, wantErr: false, }, { name: "valid bytecode 2", script: "PUSHNULL\n" + "PUSHINT32 100000000\n" + "PUSHDATA1 0x0945e5d5d2dae45c095a4f66f4d48ccba1e512db\n" + "PUSHDATA1 0x56c989e76f9a2ca05bb5caa6c96f524d905accd8\n" + "PUSH4\n" + "PACK\n" + "PUSH15\n" + "PUSHDATA1 transfer\n" + "PUSHDATA1 0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5\n" + "SYSCALL System.Contract.Call\n" + "ASSERT", bytecodeStr: "0b0200e1f5050c14db12e5a1" + "cb8cd4f4664f5a095ce4dad2" + "d5e545090c14d8cc5a904d52" + "6fc9a6cab55ba02c9a6fe789" + "c95614c01f0c087472616e73" + "6665720c14f563ea40bc283d" + "4d0e05c48ea305b3f2a07340" + "ef41627d5b5239", expected: []SyscallParameters{ { Contract: "NiHURyS83nX2mpxtA7xq84cGxVbHojj5Wc", Method: "transfer", }, }, wantErr: false, }, { name: "multiple calls", script: "PUSH1\n" + "PUSH1\n" + "PACK\n" + "PUSH3\n" + "PUSHDATA1 setRegisterPrice\n" + "PUSHDATA1 0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5\n" + "SYSCALL System.Contract.Call\n" + "PUSHDATA1 02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2\n" + "PUSH1\n" + "PACK\n" + "PUSH3\n" + "PUSHDATA1 registerCandidate\n" + "PUSHDATA1 0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5\n" + "SYSCALL System.Contract.Call\n" + "ASSERT\n" + "PUSHINT64 100000000000\n" + "PUSH1\n" + "PACK\n" + "PUSH3\n" + "PUSHDATA1 setRegisterPrice\n" + "PUSHDATA1 0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5\n" + "SYSCALL System.Contract.Call", bytecodeStr: "1111c0130c10736574526567" + "697374657250726963650c14" + "f563ea40bc283d4d0e05c48e" + "a305b3f2a07340ef41627d5b" + "520c2102b3622bf4017bdfe3" + "17c58aed5f4c753f206b7db8" + "96046fa7d774bbc4bf7f8dc2" + "11c0130c1172656769737465" + "7243616e6469646174650c14" + "f563ea40bc283d4d0e05c48e" + "a305b3f2a07340ef41627d5b" + "52390300e876481700000011" + "c0130c107365745265676973" + "74657250726963650c14f563" + "ea40bc283d4d0e05c48ea305" + "b3f2a07340ef41627d5b52", expected: []SyscallParameters{ { Contract: "NiHURyS83nX2mpxtA7xq84cGxVbHojj5Wc", Method: "setRegisterPrice", }, { Contract: "NiHURyS83nX2mpxtA7xq84cGxVbHojj5Wc", Method: "registerCandidate", }, { Contract: "NiHURyS83nX2mpxtA7xq84cGxVbHojj5Wc", Method: "setRegisterPrice", }, }, }, { name: "invalid contract address len", script: "PUSH1\n" + "PUSH1\n" + "PACK\n" + "PUSH3\n" + "PUSHDATA1 setRegisterPrice\n" + "PUSHDATA1 a1ef4073a0f2b305a38ec4050e4d3d28bc40ea63f5\n" + "SYSCALL System.Contract.Call", bytecodeStr: "1111c0130c1073657452656" + "7697374657250726963650c" + "14f563ea40bc283d4d0e05c" + "48ea305b3f2a07340efa141" + "627d5b52", expected: nil, wantErr: true, }, } func TestExtractCalls(t *testing.T) { for _, tt := range tests { bytecode := fromHexadecimalStringToBytes(tt.bytecodeStr) syscallParams, err := ExtractCalls(bytecode) if tt.wantErr { require.Error(t, err) } require.Equal(t, tt.expected, syscallParams) } }