| 
									
										
										
										
											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" | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-02 16:14:12 +01:00
										 |  |  | type ContextRef interface { | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	ReturnGas(*big.Int, *big.Int) | 
					
						
							| 
									
										
										
										
											2015-03-16 18:42:18 +01:00
										 |  |  | 	Address() common.Address | 
					
						
							| 
									
										
										
										
											2014-12-03 17:06:54 +01:00
										 |  |  | 	SetCode([]byte) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-02 16:14:12 +01:00
										 |  |  | type Context struct { | 
					
						
							| 
									
										
										
										
											2015-01-03 17:29:08 +01:00
										 |  |  | 	caller ContextRef | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 	self   ContextRef | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 	Code     []byte | 
					
						
							| 
									
										
										
										
											2015-03-17 11:19:23 +01:00
										 |  |  | 	CodeAddr *common.Address | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	value, Gas, UsedGas, Price *big.Int | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Args []byte | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-02 16:14:12 +01:00
										 |  |  | // Create a new context for the given data items | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | func NewContext(caller ContextRef, object ContextRef, value, gas, price *big.Int) *Context { | 
					
						
							|  |  |  | 	c := &Context{caller: caller, self: object, Args: nil} | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 	c.Gas = gas //new(big.Int).Set(gas) | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 	c.value = new(big.Int).Set(value) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	// In most cases price and value are pointers to transaction objects | 
					
						
							|  |  |  | 	// and we don't want the transaction's values to change. | 
					
						
							|  |  |  | 	c.Price = new(big.Int).Set(price) | 
					
						
							|  |  |  | 	c.UsedGas = new(big.Int) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return c | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-28 20:30:16 +01:00
										 |  |  | func (c *Context) GetOp(n *big.Int) OpCode { | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	return OpCode(c.GetByte(n)) | 
					
						
							| 
									
										
										
										
											2014-10-14 11:48:52 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-28 20:30:16 +01:00
										 |  |  | func (c *Context) GetByte(n *big.Int) byte { | 
					
						
							|  |  |  | 	if n.Cmp(big.NewInt(int64(len(c.Code)))) < 0 { | 
					
						
							|  |  |  | 		return c.Code[n.Int64()] | 
					
						
							| 
									
										
										
										
											2014-10-14 11:48:52 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-02 16:14:12 +01:00
										 |  |  | func (c *Context) Return(ret []byte) []byte { | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	// Return the remaining gas to the caller | 
					
						
							|  |  |  | 	c.caller.ReturnGas(c.Gas, c.Price) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-03 17:35:57 +01:00
										 |  |  | /* | 
					
						
							|  |  |  |  * Gas functions | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-03-28 20:03:25 +01:00
										 |  |  | func (c *Context) UseGas(gas *big.Int) (ok bool) { | 
					
						
							|  |  |  | 	ok = UseGas(c.Gas, gas) | 
					
						
							|  |  |  | 	if ok { | 
					
						
							|  |  |  | 		c.UsedGas.Add(c.UsedGas, gas) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-28 20:03:25 +01:00
										 |  |  | 	return | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Implement the caller interface | 
					
						
							| 
									
										
										
										
											2015-01-02 16:14:12 +01:00
										 |  |  | func (c *Context) ReturnGas(gas, price *big.Int) { | 
					
						
							|  |  |  | 	// Return the gas to the context | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	c.Gas.Add(c.Gas, gas) | 
					
						
							|  |  |  | 	c.UsedGas.Sub(c.UsedGas, gas) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-03 17:35:57 +01:00
										 |  |  | /* | 
					
						
							|  |  |  |  * Set / Get | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-03-16 18:42:18 +01:00
										 |  |  | func (c *Context) Address() common.Address { | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 	return c.self.Address() | 
					
						
							| 
									
										
										
										
											2014-12-03 17:35:57 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-02 16:14:12 +01:00
										 |  |  | func (self *Context) SetCode(code []byte) { | 
					
						
							| 
									
										
										
										
											2014-12-03 17:35:57 +01:00
										 |  |  | 	self.Code = code | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-17 11:19:23 +01:00
										 |  |  | func (self *Context) SetCallCode(addr *common.Address, code []byte) { | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 	self.Code = code | 
					
						
							|  |  |  | 	self.CodeAddr = addr | 
					
						
							|  |  |  | } |