vm

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2021 License: MIT Imports: 15 Imported by: 2

Documentation

Overview

Copyright 2017 The Elastos Dev team

The go-vm library is free software: you can redistribute it and/or modify it under the terms of the APACHA License

package vm implemented a blockchain virtual machine, which provide following main functionaries:

- opcode VM support the logic of opcode script - apiservice for external interaction API with triggered by opcode - crypto for external crypto implementations with triggered by opcode -

Index

Constants

View Source
const (
	// Constants
	PUSH0       = 0x00 // An empty array of bytes is pushed onto the stack.
	PUSHF       = PUSH0
	PUSHBYTES1  = 0x01 // 0x01-0x4B The next opcode bytes is data to be pushed onto the stack
	PUSHBYTES75 = 0x4B
	PUSHDATA1   = 0x4C // The next byte contains the number of bytes to be pushed onto the stack.
	PUSHDATA2   = 0x4D // The next two bytes contain the number of bytes to be pushed onto the stack.
	PUSHDATA4   = 0x4E // The next four bytes contain the number of bytes to be pushed onto the stack.
	PUSHM1      = 0x4F // The number -1 is pushed onto the stack.
	PUSH1       = 0x51 // The number 1 is pushed onto the stack.
	PUSHT       = PUSH1
	PUSH2       = 0x52 // The number 2 is pushed onto the stack.
	PUSH3       = 0x53 // The number 3 is pushed onto the stack.
	PUSH4       = 0x54 // The number 4 is pushed onto the stack.
	PUSH5       = 0x55 // The number 5 is pushed onto the stack.
	PUSH6       = 0x56 // The number 6 is pushed onto the stack.
	PUSH7       = 0x57 // The number 7 is pushed onto the stack.
	PUSH8       = 0x58 // The number 8 is pushed onto the stack.
	PUSH9       = 0x59 // The number 9 is pushed onto the stack.
	PUSH10      = 0x5A // The number 10 is pushed onto the stack.
	PUSH11      = 0x5B // The number 11 is pushed onto the stack.
	PUSH12      = 0x5C // The number 12 is pushed onto the stack.
	PUSH13      = 0x5D // The number 13 is pushed onto the stack.
	PUSH14      = 0x5E // The number 14 is pushed onto the stack.
	PUSH15      = 0x5F // The number 15 is pushed onto the stack.
	PUSH16      = 0x60 // The number 16 is pushed onto the stack.

	// Flow control
	NOP      = 0x61 // Does nothing.
	JMP      = 0x62
	JMPIF    = 0x63
	JMPIFNOT = 0x64
	CALL     = 0x65
	RET      = 0x66
	APPCALL  = 0x67
	SYSCALL  = 0x68

	// Stack
	TOALTSTACK   = 0x6B // Puts the input onto the top of the alt stack. Removes it from the main stack.
	FROMALTSTACK = 0x6C // Puts the input onto the top of the main stack. Removes it from the alt stack.
	XDROP        = 0x6D
	XSWAP        = 0x72
	XTUCK        = 0x73
	DEPTH        = 0x74 // Puts the number of stack items onto the stack.
	DROP         = 0x75 // Removes the top stack item.
	DUP          = 0x76 // Duplicates the top stack item.
	NIP          = 0x77 // Removes the second-to-top stack item.
	OVER         = 0x78 // Copies the second-to-top stack item to the top.
	PICK         = 0x79 // The item n back in the stack is copied to the top.
	ROLL         = 0x7A // The item n back in the stack is moved to the top.
	ROT          = 0x7B // The top three items on the stack are rotated to the left.
	SWAP         = 0x7C // The top two items on the stack are swapped.
	TUCK         = 0x7D // The item at the top of the stack is copied and inserted before the second-to-top item.

	// Splice
	CAT    = 0x7E // Concatenates two strings.
	SUBSTR = 0x7F // Returns a section of a string.
	LEFT   = 0x80 // Keeps only characters left of the specified point in a string.
	RIGHT  = 0x81 // Keeps only characters right of the specified point in a string.
	SIZE   = 0x82 // Returns the length of the input string.

	// Bitwise logic
	INVERT = 0x83 // Flips all of the bits in the input.
	AND    = 0x84 // Boolean and between each bit in the inputs.
	OR     = 0x85 // Boolean or between each bit in the inputs.
	XOR    = 0x86 // Boolean exclusive or between each bit in the inputs.
	EQUAL  = 0x87 // Returns 1 if the inputs are exactly equal, 0 otherwise.

	// Arithmetic
	// Note: Arithmetic inputs are limited to signed 32-bit integers, but may overflow their output.
	INC         = 0x8B // 1 is added to the input.
	DEC         = 0x8C // 1 is subtracted from the input.
	SAL         = 0x8D // The input is multiplied by 2.
	SAR         = 0x8E // The input is divided by 2.
	NEGATE      = 0x8F // The sign of the input is flipped.
	ABS         = 0x90 // The input is made positive.
	NOT         = 0x91 // If the input is 0 or 1, it is flipped. Otherwise the output will be 0.
	NZ          = 0x92 // Returns 0 if the input is 0. 1 otherwise.
	ADD         = 0x93 // a is added to b.
	SUB         = 0x94 // b is subtracted from a.
	MUL         = 0x95 // a is multiplied by b.
	DIV         = 0x96 // a is divided by b.
	MOD         = 0x97 // Returns the remainder after dividing a by b.
	SHL         = 0x98 // Shifts a left b bits, preserving sign.
	SHR         = 0x99 // Shifts a right b bits, preserving sign.
	BOOLAND     = 0x9A // If both a and b are not 0, the output is 1. Otherwise 0.
	BOOLOR      = 0x9B // If a or b is not 0, the output is 1. Otherwise 0.
	NUMEQUAL    = 0x9C // Returns 1 if the numbers are equal, 0 otherwise.
	NUMNOTEQUAL = 0x9E // Returns 1 if the numbers are not equal, 0 otherwise.
	LT          = 0x9F // Returns 1 if a is less than b, 0 otherwise.
	GT          = 0xA0 // Returns 1 if a is greater than b, 0 otherwise.
	LTE         = 0xA1 // Returns 1 if a is less than or equal to b, 0 otherwise.
	GTE         = 0xA2 // Returns 1 if a is greater than or equal to b, 0 otherwise.
	MIN         = 0xA3 // Returns the smaller of a and b.
	MAX         = 0xA4 // Returns the larger of a and b.
	WITHIN      = 0xA5 // Returns 1 if x is within the specified range (left-inclusive), 0 otherwise.

	// Crypto
	//RIPEMD160 = 0xA6 // The input is hashed using RIPEMD-160.
	SHA1          = 0xA7 // The input is hashed using SHA-1.
	SHA256        = 0xA8 // The input is hashed using SHA-256.
	HASH160       = 0xA9
	HASH256       = 0xAA
	CHECKSIG      = 0xAC // The entire transaction's outputs inputs and script (from the most recently-executed CODESEPARATOR to the end) are hashed. The signature used by CHECKSIG must be a valid signature for this hash and public key. If it is 1 is returned 0 otherwise.
	CHECKREGID    = 0xAD
	CHECKMULTISIG = 0xAE // For each signature and public key pair CHECKSIG is executed. If more public keys than signatures are listed some key/sig pairs can fail. All signatures need to match a public key. If all signatures are valid 1 is returned 0 otherwise. Due to a bug one extra unused value is removed from the stack.

	// Array
	ARRAYSIZE = 0xC0
	PACK      = 0xC1
	UNPACK    = 0xC2
	PICKITEM  = 0xC3
)
View Source
const MAXSTEPS int = 1200

Variables

View Source
var (
	OpExecList = [256]OpExec{

		PUSH0:       {PUSH0, "0", opPushData},
		PUSHBYTES1:  {PUSHBYTES1, "PUSHBYTES1", opPushData},
		PUSHBYTES75: {PUSHBYTES75, "PUSHBYTES75", opPushData},
		PUSHDATA1:   {PUSHDATA1, "PUSHDATA1", opPushData},
		PUSHDATA2:   {PUSHDATA2, "PUSHDATA2", opPushData},
		PUSHDATA4:   {PUSHDATA4, "PUSHDATA4", opPushData},
		PUSHM1:      {PUSHM1, "PUSHM1", opPushData},
		PUSH1:       {PUSH1, "1", opPushData},
		PUSH2:       {PUSH2, "2", opPushData},
		PUSH3:       {PUSH3, "3", opPushData},
		PUSH4:       {PUSH4, "4", opPushData},
		PUSH5:       {PUSH5, "5", opPushData},
		PUSH6:       {PUSH6, "6", opPushData},
		PUSH7:       {PUSH7, "7", opPushData},
		PUSH8:       {PUSH8, "8", opPushData},
		PUSH9:       {PUSH9, "9", opPushData},
		PUSH10:      {PUSH10, "10", opPushData},
		PUSH11:      {PUSH11, "11", opPushData},
		PUSH12:      {PUSH12, "12", opPushData},
		PUSH13:      {PUSH13, "13", opPushData},
		PUSH14:      {PUSH14, "14", opPushData},
		PUSH15:      {PUSH15, "15", opPushData},
		PUSH16:      {PUSH16, "16", opPushData},

		NOP:      {NOP, "NOP", opNop},
		JMP:      {JMP, "JMP", opJmp},
		JMPIF:    {JMPIF, "JMPIF", opJmp},
		JMPIFNOT: {JMPIFNOT, "JMPIFNOT", opJmp},
		CALL:     {CALL, "CALL", opCall},
		RET:      {RET, "RET", opRet},
		APPCALL:  {APPCALL, "APPCALL", opAppCall},
		SYSCALL:  {SYSCALL, "SYSCALL", opSysCall},

		TOALTSTACK:   {TOALTSTACK, "TOALTSTACK", opToAltStack},
		FROMALTSTACK: {FROMALTSTACK, "FROMALTSTACK", opFromAltStack},
		XDROP:        {XDROP, "XDROP", opXDrop},
		XSWAP:        {XSWAP, "XSWAPP", opXSwap},
		XTUCK:        {XTUCK, "XTUCK", opXTuck},
		DEPTH:        {DEPTH, "DEPTH", opDepth},
		DROP:         {DROP, "DROP", opDrop},
		DUP:          {DUP, "DUP", opDup},
		NIP:          {NIP, "NIP", opNip},
		OVER:         {OVER, "OVER", opOver},
		PICK:         {PICK, "PICK", opPick},
		ROLL:         {ROLL, "ROLL", opRoll},
		ROT:          {ROT, "ROT", opRot},
		SWAP:         {SWAP, "SWAP", opSwap},
		TUCK:         {TUCK, "TUCK", opTuck},

		CAT:    {CAT, "CAT", opCat},
		SUBSTR: {SUBSTR, "SUBSTR", opSubStr},
		LEFT:   {LEFT, "LEFT", opLeft},
		RIGHT:  {RIGHT, "RIGHT", opRight},
		SIZE:   {SIZE, "SIZE", opSize},

		INVERT: {INVERT, "INVERT", opInvert},
		AND:    {AND, "AND", opBigIntZip},
		OR:     {OR, "OR", opBigIntZip},
		XOR:    {XOR, "XOR", opBigIntZip},
		EQUAL:  {EQUAL, "EQUAL", opEqual},

		INC:         {INC, "INC", opBigInt},
		DEC:         {DEC, "DEC", opBigInt},
		SAL:         {SAL, "SAL", opBigInt},
		SAR:         {SAR, "SAR", opBigInt},
		NEGATE:      {NEGATE, "NEGATE", opBigInt},
		ABS:         {ABS, "ABS", opBigInt},
		NOT:         {NOT, "NOT", opNot},
		NZ:          {NZ, "NZ", opNz},
		ADD:         {ADD, "ADD", opBigIntZip},
		SUB:         {SUB, "SUB", opBigIntZip},
		MUL:         {MUL, "MUL", opBigIntZip},
		DIV:         {DIV, "DIV", opBigIntZip},
		MOD:         {MOD, "MOD", opBigIntZip},
		SHL:         {SHL, "SHL", opBigIntZip},
		SHR:         {SHR, "SHR", opBigIntZip},
		BOOLAND:     {BOOLAND, "BOOLAND", opBoolZip},
		BOOLOR:      {BOOLOR, "BOOLOR", opBoolZip},
		NUMEQUAL:    {NUMEQUAL, "NUMEQUAL", opBigIntComp},
		NUMNOTEQUAL: {NUMNOTEQUAL, "NUMNOTEQUAL", opBigIntComp},
		LT:          {LT, "LT", opBigIntComp},
		GT:          {GT, "GT", opBigIntComp},
		LTE:         {LTE, "LTE", opBigIntComp},
		GTE:         {GTE, "GTE", opBigIntComp},
		MIN:         {MIN, "MIN", opBigIntZip},
		MAX:         {MAX, "MAX", opBigIntZip},
		WITHIN:      {WITHIN, "WITHIN", opWithIn},

		SHA1:          {SHA1, "SHA1", opHash},
		SHA256:        {SHA256, "SHA256", opHash},
		HASH160:       {HASH160, "HASH160", opHash},
		HASH256:       {HASH256, "HASH256", opHash},
		CHECKSIG:      {CHECKSIG, "CHECKSIG", opCheckSig},
		CHECKREGID:    {CHECKREGID, "CHECKREGID", opCheckSig},
		CHECKMULTISIG: {CHECKMULTISIG, "CHECKMULTISIG", opCheckMultiSig},

		ARRAYSIZE: {ARRAYSIZE, "ARRAYSIZE", opArraySize},
		PACK:      {PACK, "PACK", opPack},
		UNPACK:    {UNPACK, "UNPACK", opUnpack},
		PICKITEM:  {PICKITEM, "PICKITEM", opPickItem},
	}
)

Functions

func AsBool

func AsBool(e interface{}) bool

func AsInt64

func AsInt64(b []byte) (int64, error)

func AssertStackItem

func AssertStackItem(stackItem interface{}) types.StackItem

func BigIntComp

func BigIntComp(bigint *big.Int, op OpCode) bool

func BigIntMultiComp

func BigIntMultiComp(ints1 *big.Int, ints2 *big.Int, op OpCode) bool

func BigIntOp

func BigIntOp(bi *big.Int, op OpCode) *big.Int

func BigIntZip

func BigIntZip(ints1 *big.Int, ints2 *big.Int, op OpCode) *big.Int

func BoolArrayOp

func BoolArrayOp(bools []bool, op OpCode) []bool

func BoolZip

func BoolZip(bi1 bool, bi2 bool, op OpCode) bool

func ByteArrZip

func ByteArrZip(s1 []byte, s2 []byte, op OpCode) []byte

func Concat

func Concat(array1 []byte, array2 []byte) []byte

func Hash

func Hash(b []byte, e *ExecutionEngine) []byte

func IsEqual

func IsEqual(v1 interface{}, v2 interface{}) bool

func IsEqualBytes

func IsEqualBytes(b1 []byte, b2 []byte) bool

func MaxBigInt

func MaxBigInt(ints []big.Int) big.Int

func MaxInt64

func MaxInt64(datas []int64) int64

func MinBigInt

func MinBigInt(ints []big.Int) big.Int

func MinInt64

func MinInt64(datas []int64) int64

func NewStackItem

func NewStackItem(data interface{}) (types.StackItem, error)

func NewStackItems

func NewStackItems() []types.StackItem

func SumBigInt

func SumBigInt(ints []big.Int) big.Int

common func

func ToBigInt

func ToBigInt(data interface{}) *big.Int

func WithInOp

func WithInOp(int1 *big.Int, int2 *big.Int, int3 *big.Int) bool

Types

type BigIntSorter

type BigIntSorter []big.Int

func (BigIntSorter) Len

func (c BigIntSorter) Len() int

func (BigIntSorter) Less

func (c BigIntSorter) Less(i, j int) bool

func (BigIntSorter) Swap

func (c BigIntSorter) Swap(i, j int)

type CryptoECDsa

type CryptoECDsa struct {
}

func (*CryptoECDsa) Hash168

func (c *CryptoECDsa) Hash168(data []byte) []byte

func (*CryptoECDsa) Hash256

func (c *CryptoECDsa) Hash256(data []byte) []byte

func (*CryptoECDsa) VerifySignature

func (c *CryptoECDsa) VerifySignature(data []byte, signature []byte, pubkey []byte) error

type ExecutionContext

type ExecutionContext struct {
	Script             []byte
	OpReader           *utils.VmReader
	PushOnly           bool
	BreakPoints        []uint
	InstructionPointer int
}

func AssertExecutionContext

func AssertExecutionContext(context interface{}) *ExecutionContext

func NewExecutionContext

func NewExecutionContext(script []byte, pushOnly bool, breakPoints []uint) *ExecutionContext

func (*ExecutionContext) Clone

func (ec *ExecutionContext) Clone() *ExecutionContext

func (*ExecutionContext) NextInstruction

func (ec *ExecutionContext) NextInstruction() OpCode

type ExecutionEngine

type ExecutionEngine struct {
	// contains filtered or unexported fields
}

func NewExecutionEngine

func NewExecutionEngine(container interfaces.IDataContainer, crypto interfaces.ICrypto, maxSteps int, table interfaces.IScriptTable, service *GeneralService) *ExecutionEngine

func (*ExecutionEngine) AddBreakPoint

func (e *ExecutionEngine) AddBreakPoint(position uint)

func (*ExecutionEngine) CallingScript

func (e *ExecutionEngine) CallingScript() []byte

func (*ExecutionEngine) EntryScript

func (e *ExecutionEngine) EntryScript() []byte

func (*ExecutionEngine) Execute

func (e *ExecutionEngine) Execute()

func (*ExecutionEngine) ExecuteOp

func (e *ExecutionEngine) ExecuteOp(opCode OpCode, context *ExecutionContext) (VMState, error)

func (*ExecutionEngine) ExecutingScript

func (e *ExecutionEngine) ExecutingScript() []byte

func (*ExecutionEngine) GetEvaluationStack

func (e *ExecutionEngine) GetEvaluationStack() *utils.RandomAccessStack

func (*ExecutionEngine) GetExecuteResult

func (e *ExecutionEngine) GetExecuteResult() bool

func (*ExecutionEngine) GetState

func (e *ExecutionEngine) GetState() VMState

func (*ExecutionEngine) LoadScript

func (e *ExecutionEngine) LoadScript(script []byte, pushOnly bool)

func (*ExecutionEngine) RemoveBreakPoint

func (e *ExecutionEngine) RemoveBreakPoint(position uint) bool

func (*ExecutionEngine) StepInto

func (e *ExecutionEngine) StepInto()

func (*ExecutionEngine) StepOut

func (e *ExecutionEngine) StepOut()

func (*ExecutionEngine) StepOver

func (e *ExecutionEngine) StepOver()

type GeneralService

type GeneralService struct {
	// contains filtered or unexported fields
}

func NewGeneralService

func NewGeneralService() *GeneralService

func (*GeneralService) GetCallingScriptHash

func (is *GeneralService) GetCallingScriptHash(engine *ExecutionEngine) bool

func (*GeneralService) GetEntryScriptHash

func (is *GeneralService) GetEntryScriptHash(engine *ExecutionEngine) bool

func (*GeneralService) GetExecutingScriptHash

func (is *GeneralService) GetExecutingScriptHash(engine *ExecutionEngine) bool

func (*GeneralService) GetScriptContainer

func (is *GeneralService) GetScriptContainer(engine *ExecutionEngine) bool

func (*GeneralService) Invoke

func (is *GeneralService) Invoke(method string, engine *ExecutionEngine) bool

func (*GeneralService) Register

func (is *GeneralService) Register(method string, handler func(*ExecutionEngine) bool) bool

type OpCode

type OpCode byte

type OpExec

type OpExec struct {
	Opcode OpCode
	Name   string
	Exec   func(*ExecutionEngine) (VMState, error)
}

type VMState

type VMState byte
const (
	NONE  VMState = 0
	HALT  VMState = 1 << 0
	FAULT VMState = 1 << 1
	BREAK VMState = 1 << 2

	INSUFFICIENT_RESOURCE VMState = 1 << 4
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL