evm-core 0.14.0

Portable Ethereum Virtual Machine implementation written in pure Rust.
Documentation
/// Opcode enum. One-to-one corresponding to an `u8` value.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Opcode {
	Stop,
	Add,
	Mul,
	Sub,
	Div,
	SDiv,
	Mod,
	SMod,
	AddMod,
	MulMod,
	Exp,
	SignExtend,

	Lt,
	Gt,
	SLt,
	SGt,
	Eq,
	IsZero,
	And,
	Or,
	Xor,
	Not,
	Byte,

	CallDataLoad,
	CallDataSize,
	CallDataCopy,
	CodeSize,
	CodeCopy,

	Shl,
	Shr,
	Sar,

	Pop,
	MLoad,
	MStore,
	MStore8,
	Jump,
	JumpI,
	PC,
	MSize,
	JumpDest,

	Push(u8),
	Dup(u8),
	Swap(u8),

	Return,
	Revert,

	Invalid,
}

impl Opcode {
	pub fn parse(opcode: u8) -> Result<Opcode, ExternalOpcode> {
		match opcode {
			0x00 => Ok(Opcode::Stop),
			0x01 => Ok(Opcode::Add),
			0x02 => Ok(Opcode::Mul),
			0x03 => Ok(Opcode::Sub),
			0x04 => Ok(Opcode::Div),
			0x05 => Ok(Opcode::SDiv),
			0x06 => Ok(Opcode::Mod),
			0x07 => Ok(Opcode::SMod),
			0x08 => Ok(Opcode::AddMod),
			0x09 => Ok(Opcode::MulMod),
			0x0a => Ok(Opcode::Exp),
			0x0b => Ok(Opcode::SignExtend),

			0x10 => Ok(Opcode::Lt),
			0x11 => Ok(Opcode::Gt),
			0x12 => Ok(Opcode::SLt),
			0x13 => Ok(Opcode::SGt),
			0x14 => Ok(Opcode::Eq),
			0x15 => Ok(Opcode::IsZero),
			0x16 => Ok(Opcode::And),
			0x17 => Ok(Opcode::Or),
			0x18 => Ok(Opcode::Xor),
			0x19 => Ok(Opcode::Not),
			0x1a => Ok(Opcode::Byte),

			0x1b => Ok(Opcode::Shl),
			0x1c => Ok(Opcode::Shr),
			0x1d => Ok(Opcode::Sar),

			0x20 => Err(ExternalOpcode::Sha3),

			0x30 => Err(ExternalOpcode::Address),
			0x31 => Err(ExternalOpcode::Balance),
			0x32 => Err(ExternalOpcode::Origin),
			0x33 => Err(ExternalOpcode::Caller),
			0x34 => Err(ExternalOpcode::CallValue),
			0x35 => Ok(Opcode::CallDataLoad),
			0x36 => Ok(Opcode::CallDataSize),
			0x37 => Ok(Opcode::CallDataCopy),
			0x38 => Ok(Opcode::CodeSize),
			0x39 => Ok(Opcode::CodeCopy),
			0x3a => Err(ExternalOpcode::GasPrice),
			0x3b => Err(ExternalOpcode::ExtCodeSize),
			0x3c => Err(ExternalOpcode::ExtCodeCopy),
			0x3d => Err(ExternalOpcode::ReturnDataSize),
			0x3e => Err(ExternalOpcode::ReturnDataCopy),
			0x3f => Err(ExternalOpcode::ExtCodeHash),

			0x40 => Err(ExternalOpcode::BlockHash),
			0x41 => Err(ExternalOpcode::Coinbase),
			0x42 => Err(ExternalOpcode::Timestamp),
			0x43 => Err(ExternalOpcode::Number),
			0x44 => Err(ExternalOpcode::Difficulty),
			0x45 => Err(ExternalOpcode::GasLimit),
			0x46 => Err(ExternalOpcode::ChainId),
			0x47 => Err(ExternalOpcode::SelfBalance),

			0x50 => Ok(Opcode::Pop),
			0x51 => Ok(Opcode::MLoad),
			0x52 => Ok(Opcode::MStore),
			0x53 => Ok(Opcode::MStore8),
			0x54 => Err(ExternalOpcode::SLoad),
			0x55 => Err(ExternalOpcode::SStore),
			0x56 => Ok(Opcode::Jump),
			0x57 => Ok(Opcode::JumpI),
			0x58 => Ok(Opcode::PC),
			0x59 => Ok(Opcode::MSize),
			0x5a => Err(ExternalOpcode::Gas),
			0x5b => Ok(Opcode::JumpDest),

			0x60 => Ok(Opcode::Push(1)),
			0x61 => Ok(Opcode::Push(2)),
			0x62 => Ok(Opcode::Push(3)),
			0x63 => Ok(Opcode::Push(4)),
			0x64 => Ok(Opcode::Push(5)),
			0x65 => Ok(Opcode::Push(6)),
			0x66 => Ok(Opcode::Push(7)),
			0x67 => Ok(Opcode::Push(8)),
			0x68 => Ok(Opcode::Push(9)),
			0x69 => Ok(Opcode::Push(10)),
			0x6a => Ok(Opcode::Push(11)),
			0x6b => Ok(Opcode::Push(12)),
			0x6c => Ok(Opcode::Push(13)),
			0x6d => Ok(Opcode::Push(14)),
			0x6e => Ok(Opcode::Push(15)),
			0x6f => Ok(Opcode::Push(16)),
			0x70 => Ok(Opcode::Push(17)),
			0x71 => Ok(Opcode::Push(18)),
			0x72 => Ok(Opcode::Push(19)),
			0x73 => Ok(Opcode::Push(20)),
			0x74 => Ok(Opcode::Push(21)),
			0x75 => Ok(Opcode::Push(22)),
			0x76 => Ok(Opcode::Push(23)),
			0x77 => Ok(Opcode::Push(24)),
			0x78 => Ok(Opcode::Push(25)),
			0x79 => Ok(Opcode::Push(26)),
			0x7a => Ok(Opcode::Push(27)),
			0x7b => Ok(Opcode::Push(28)),
			0x7c => Ok(Opcode::Push(29)),
			0x7d => Ok(Opcode::Push(30)),
			0x7e => Ok(Opcode::Push(31)),
			0x7f => Ok(Opcode::Push(32)),

			0x80 => Ok(Opcode::Dup(1)),
			0x81 => Ok(Opcode::Dup(2)),
			0x82 => Ok(Opcode::Dup(3)),
			0x83 => Ok(Opcode::Dup(4)),
			0x84 => Ok(Opcode::Dup(5)),
			0x85 => Ok(Opcode::Dup(6)),
			0x86 => Ok(Opcode::Dup(7)),
			0x87 => Ok(Opcode::Dup(8)),
			0x88 => Ok(Opcode::Dup(9)),
			0x89 => Ok(Opcode::Dup(10)),
			0x8a => Ok(Opcode::Dup(11)),
			0x8b => Ok(Opcode::Dup(12)),
			0x8c => Ok(Opcode::Dup(13)),
			0x8d => Ok(Opcode::Dup(14)),
			0x8e => Ok(Opcode::Dup(15)),
			0x8f => Ok(Opcode::Dup(16)),

			0x90 => Ok(Opcode::Swap(1)),
			0x91 => Ok(Opcode::Swap(2)),
			0x92 => Ok(Opcode::Swap(3)),
			0x93 => Ok(Opcode::Swap(4)),
			0x94 => Ok(Opcode::Swap(5)),
			0x95 => Ok(Opcode::Swap(6)),
			0x96 => Ok(Opcode::Swap(7)),
			0x97 => Ok(Opcode::Swap(8)),
			0x98 => Ok(Opcode::Swap(9)),
			0x99 => Ok(Opcode::Swap(10)),
			0x9a => Ok(Opcode::Swap(11)),
			0x9b => Ok(Opcode::Swap(12)),
			0x9c => Ok(Opcode::Swap(13)),
			0x9d => Ok(Opcode::Swap(14)),
			0x9e => Ok(Opcode::Swap(15)),
			0x9f => Ok(Opcode::Swap(16)),

			0xa0 => Err(ExternalOpcode::Log(0)),
			0xa1 => Err(ExternalOpcode::Log(1)),
			0xa2 => Err(ExternalOpcode::Log(2)),
			0xa3 => Err(ExternalOpcode::Log(3)),
			0xa4 => Err(ExternalOpcode::Log(4)),

			0xf0 => Err(ExternalOpcode::Create),
			0xf1 => Err(ExternalOpcode::Call),
			0xf2 => Err(ExternalOpcode::CallCode),
			0xf3 => Ok(Opcode::Return),
			0xf4 => Err(ExternalOpcode::DelegateCall),
			0xf5 => Err(ExternalOpcode::Create2),
			0xfa => Err(ExternalOpcode::StaticCall),
			0xfd => Ok(Opcode::Revert),

			0xff => Err(ExternalOpcode::Suicide),
			other => Err(ExternalOpcode::Other(other)),
		}
	}
}

/// External opcodes.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ExternalOpcode {
	Sha3,
	Address,
	Balance,
	SelfBalance,
	Origin,
	Caller,
	CallValue,
	GasPrice,
	ExtCodeSize,
	ExtCodeCopy,
	ExtCodeHash,
	ReturnDataSize,
	ReturnDataCopy,
	BlockHash,
	Coinbase,
	Timestamp,
	Number,
	Difficulty,
	GasLimit,
	SLoad,
	SStore,
	Gas,
	Log(u8),
	Create,
	Create2,
	Call,
	CallCode,
	DelegateCall,
	StaticCall,
	Suicide,
	ChainId,
	Other(u8),
}