| 
									
										
										
										
											2016-04-14 18:18:24 +02:00
										 |  |  | // Copyright 2015 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-23 18:35:11 +02:00
										 |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-18 13:31:20 +02:00
										 |  |  | package vm | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2014-08-11 16:23:38 +02:00
										 |  |  | 	"math/big" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | 	"github.com/holiman/uint256" | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-30 10:19:10 +02:00
										 |  |  | // ContractRef is a reference to the contract's backing object | 
					
						
							|  |  |  | type ContractRef interface { | 
					
						
							| 
									
										
										
										
											2015-03-16 18:42:18 +01:00
										 |  |  | 	Address() common.Address | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 23:29:59 +01:00
										 |  |  | // AccountRef implements ContractRef. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Account references are used during EVM initialisation and | 
					
						
							|  |  |  | // it's primary use is to fetch addresses. Removing this object | 
					
						
							|  |  |  | // proves difficult because of the cached jump destinations which | 
					
						
							|  |  |  | // are fetched from the parent contract (i.e. the caller), which | 
					
						
							|  |  |  | // is a ContractRef. | 
					
						
							|  |  |  | type AccountRef common.Address | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Address casts AccountRef to a Address | 
					
						
							|  |  |  | func (ar AccountRef) Address() common.Address { return (common.Address)(ar) } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-30 10:19:10 +02:00
										 |  |  | // Contract represents an ethereum contract in the state database. It contains | 
					
						
							| 
									
										
										
										
											2018-08-27 16:49:29 +08:00
										 |  |  | // the contract code, calling arguments. Contract implements ContractRef | 
					
						
							| 
									
										
										
										
											2015-08-30 10:19:10 +02:00
										 |  |  | type Contract struct { | 
					
						
							| 
									
										
										
										
											2016-01-19 23:50:00 +01:00
										 |  |  | 	// CallerAddress is the result of the caller which initialised this | 
					
						
							|  |  |  | 	// contract. However when the "call method" is delegated this value | 
					
						
							|  |  |  | 	// needs to be initialised to that of the caller's caller. | 
					
						
							|  |  |  | 	CallerAddress common.Address | 
					
						
							|  |  |  | 	caller        ContractRef | 
					
						
							|  |  |  | 	self          ContractRef | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 	jumpdests map[common.Hash]bitvec // Aggregated result of JUMPDEST analysis. | 
					
						
							|  |  |  | 	analysis  bitvec                 // Locally cached result of JUMPDEST analysis | 
					
						
							| 
									
										
										
										
											2015-05-29 14:40:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 	Code     []byte | 
					
						
							| 
									
										
										
										
											2016-10-01 15:44:53 +03:00
										 |  |  | 	CodeHash common.Hash | 
					
						
							| 
									
										
										
										
											2015-03-17 11:19:23 +01:00
										 |  |  | 	CodeAddr *common.Address | 
					
						
							| 
									
										
										
										
											2016-10-01 15:44:53 +03:00
										 |  |  | 	Input    []byte | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 20:17:24 +01:00
										 |  |  | 	Gas   uint64 | 
					
						
							|  |  |  | 	value *big.Int | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 23:50:00 +01:00
										 |  |  | // NewContract returns a new contract environment for the execution of EVM. | 
					
						
							| 
									
										
										
										
											2017-01-04 20:17:24 +01:00
										 |  |  | func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uint64) *Contract { | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 	c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-30 10:19:10 +02:00
										 |  |  | 	if parent, ok := caller.(*Contract); ok { | 
					
						
							| 
									
										
										
										
											2015-05-29 14:40:45 +02:00
										 |  |  | 		// Reuse JUMPDEST analysis from parent context if available. | 
					
						
							|  |  |  | 		c.jumpdests = parent.jumpdests | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 		c.jumpdests = make(map[common.Hash]bitvec) | 
					
						
							| 
									
										
										
										
											2015-05-29 14:40:45 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	// Gas should be a pointer so it can safely be reduced through the run | 
					
						
							|  |  |  | 	// This pointer will be off the state transition | 
					
						
							| 
									
										
										
										
											2017-01-04 20:17:24 +01:00
										 |  |  | 	c.Gas = gas | 
					
						
							| 
									
										
										
										
											2017-02-22 23:29:59 +01:00
										 |  |  | 	// ensures a value is set | 
					
						
							|  |  |  | 	c.value = value | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return c | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | func (c *Contract) validJumpdest(dest *uint256.Int) bool { | 
					
						
							|  |  |  | 	udest, overflow := dest.Uint64WithOverflow() | 
					
						
							|  |  |  | 	// PC cannot go beyond len(code) and certainly can't be bigger than 63bits. | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 	// Don't bother checking for JUMPDEST in that case. | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | 	if overflow || udest >= uint64(len(c.Code)) { | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Only JUMPDESTs allowed for destinations | 
					
						
							|  |  |  | 	if OpCode(c.Code[udest]) != JUMPDEST { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | 	return c.isCode(udest) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *Contract) validJumpSubdest(udest uint64) bool { | 
					
						
							|  |  |  | 	// PC cannot go beyond len(code) and certainly can't be bigger than 63 bits. | 
					
						
							|  |  |  | 	// Don't bother checking for BEGINSUB in that case. | 
					
						
							|  |  |  | 	if int64(udest) < 0 || udest >= uint64(len(c.Code)) { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Only BEGINSUBs allowed for destinations | 
					
						
							|  |  |  | 	if OpCode(c.Code[udest]) != BEGINSUB { | 
					
						
							|  |  |  | 		return false | 
					
						
							| 
									
										
										
										
											2020-05-25 16:12:48 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | 	return c.isCode(udest) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // isCode returns true if the provided PC location is an actual opcode, as | 
					
						
							|  |  |  | // opposed to a data-segment following a PUSHN operation. | 
					
						
							|  |  |  | func (c *Contract) isCode(udest uint64) bool { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:40:23 +02:00
										 |  |  | 	// Do we already have an analysis laying around? | 
					
						
							|  |  |  | 	if c.analysis != nil { | 
					
						
							|  |  |  | 		return c.analysis.codeSegment(udest) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | 	// Do we have a contract hash already? | 
					
						
							| 
									
										
										
										
											2020-08-04 15:40:23 +02:00
										 |  |  | 	// If we do have a hash, that means it's a 'regular' contract. For regular | 
					
						
							|  |  |  | 	// contracts ( not temporary initcode), we store the analysis in a map | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 	if c.CodeHash != (common.Hash{}) { | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | 		// Does parent context have the analysis? | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 		analysis, exist := c.jumpdests[c.CodeHash] | 
					
						
							|  |  |  | 		if !exist { | 
					
						
							|  |  |  | 			// Do the analysis and save in parent context | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | 			// We do not need to store it in c.analysis | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 			analysis = codeBitmap(c.Code) | 
					
						
							|  |  |  | 			c.jumpdests[c.CodeHash] = analysis | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-05-25 16:12:48 +02:00
										 |  |  | 		// Also stash it in current contract for faster access | 
					
						
							|  |  |  | 		c.analysis = analysis | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 		return analysis.codeSegment(udest) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// We don't have the code hash, most likely a piece of initcode not already | 
					
						
							|  |  |  | 	// in state trie. In that case, we do an analysis, and save it locally, so | 
					
						
							|  |  |  | 	// we don't have to recalculate it for every JUMP instruction in the execution | 
					
						
							|  |  |  | 	// However, we don't save it within the parent context | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | 	if c.analysis == nil { | 
					
						
							|  |  |  | 		c.analysis = codeBitmap(c.Code) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 	return c.analysis.codeSegment(udest) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 23:50:00 +01:00
										 |  |  | // AsDelegate sets the contract to be a delegate call and returns the current | 
					
						
							|  |  |  | // contract (for chaining calls) | 
					
						
							|  |  |  | func (c *Contract) AsDelegate() *Contract { | 
					
						
							|  |  |  | 	// NOTE: caller must, at all times be a contract. It should never happen | 
					
						
							|  |  |  | 	// that caller is something other than a Contract. | 
					
						
							| 
									
										
										
										
											2017-02-22 23:29:59 +01:00
										 |  |  | 	parent := c.caller.(*Contract) | 
					
						
							|  |  |  | 	c.CallerAddress = parent.CallerAddress | 
					
						
							|  |  |  | 	c.value = parent.value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 23:50:00 +01:00
										 |  |  | 	return c | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-30 10:19:10 +02:00
										 |  |  | // GetOp returns the n'th element in the contract's byte array | 
					
						
							|  |  |  | func (c *Contract) GetOp(n uint64) OpCode { | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	return OpCode(c.GetByte(n)) | 
					
						
							| 
									
										
										
										
											2014-10-14 11:48:52 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-30 10:19:10 +02:00
										 |  |  | // GetByte returns the n'th byte in the contract's byte array | 
					
						
							|  |  |  | func (c *Contract) GetByte(n uint64) byte { | 
					
						
							| 
									
										
										
										
											2015-06-10 10:44:46 +02:00
										 |  |  | 	if n < uint64(len(c.Code)) { | 
					
						
							|  |  |  | 		return c.Code[n] | 
					
						
							| 
									
										
										
										
											2014-10-14 11:48:52 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 23:50:00 +01:00
										 |  |  | // Caller returns the caller of the contract. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Caller will recursively call caller when the contract is a delegate | 
					
						
							|  |  |  | // call, including that of caller's caller. | 
					
						
							|  |  |  | func (c *Contract) Caller() common.Address { | 
					
						
							|  |  |  | 	return c.CallerAddress | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-30 10:19:10 +02:00
										 |  |  | // UseGas attempts the use gas and subtracts it and returns true on success | 
					
						
							| 
									
										
										
										
											2017-01-04 20:17:24 +01:00
										 |  |  | func (c *Contract) UseGas(gas uint64) (ok bool) { | 
					
						
							|  |  |  | 	if c.Gas < gas { | 
					
						
							|  |  |  | 		return false | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-04 20:17:24 +01:00
										 |  |  | 	c.Gas -= gas | 
					
						
							|  |  |  | 	return true | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-30 10:19:10 +02:00
										 |  |  | // Address returns the contracts address | 
					
						
							|  |  |  | func (c *Contract) Address() common.Address { | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 	return c.self.Address() | 
					
						
							| 
									
										
										
										
											2014-12-03 17:35:57 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-07 17:53:16 +08:00
										 |  |  | // Value returns the contract's value (sent to it from it's caller) | 
					
						
							| 
									
										
										
										
											2015-11-27 15:40:29 +01:00
										 |  |  | func (c *Contract) Value() *big.Int { | 
					
						
							|  |  |  | 	return c.value | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-31 17:09:50 +02:00
										 |  |  | // SetCallCode sets the code of the contract and address of the backing data | 
					
						
							|  |  |  | // object | 
					
						
							| 
									
										
										
										
											2018-05-02 01:27:59 -07:00
										 |  |  | func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) { | 
					
						
							|  |  |  | 	c.Code = code | 
					
						
							|  |  |  | 	c.CodeHash = hash | 
					
						
							|  |  |  | 	c.CodeAddr = addr | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-10-04 17:15:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // SetCodeOptionalHash can be used to provide code, but it's optional to provide hash. | 
					
						
							|  |  |  | // In case hash is not provided, the jumpdest analysis will not be saved to the parent context | 
					
						
							|  |  |  | func (c *Contract) SetCodeOptionalHash(addr *common.Address, codeAndHash *codeAndHash) { | 
					
						
							|  |  |  | 	c.Code = codeAndHash.code | 
					
						
							|  |  |  | 	c.CodeHash = codeAndHash.hash | 
					
						
							|  |  |  | 	c.CodeAddr = addr | 
					
						
							|  |  |  | } |