transaction.go 4.6 KB
Newer Older
1
package types
O
obscuren 已提交
2 3

import (
O
obscuren 已提交
4
	"fmt"
5 6
	"math/big"

O
obscuren 已提交
7
	"github.com/ethereum/go-ethereum/crypto"
8
	"github.com/ethereum/go-ethereum/ethutil"
O
obscuren 已提交
9 10 11
	"github.com/obscuren/secp256k1-go"
)

12
func IsContractAddr(addr []byte) bool {
13
	return len(addr) == 0
14 15
}

O
obscuren 已提交
16
type Transaction struct {
17 18 19 20 21 22
	nonce     uint64
	recipient []byte
	value     *big.Int
	gas       *big.Int
	gasPrice  *big.Int
	data      []byte
O
obscuren 已提交
23 24 25 26
	v         byte
	r, s      []byte
}

O
obscuren 已提交
27
func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction {
O
obscuren 已提交
28
	return &Transaction{recipient: nil, value: value, gas: gas, gasPrice: gasPrice, data: script}
29 30
}

31
func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction {
O
obscuren 已提交
32
	return &Transaction{recipient: to, value: value, gasPrice: gasPrice, gas: gas, data: data}
33 34
}

O
obscuren 已提交
35
func NewTransactionFromBytes(data []byte) *Transaction {
O
obscuren 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49
	tx := &Transaction{}
	tx.RlpDecode(data)

	return tx
}

func NewTransactionFromValue(val *ethutil.Value) *Transaction {
	tx := &Transaction{}
	tx.RlpValueDecode(val)

	return tx
}

func (tx *Transaction) Hash() []byte {
50
	data := []interface{}{tx.Nonce, tx.gasPrice, tx.gas, tx.recipient, tx.Value, tx.Data}
51

O
obscuren 已提交
52
	return crypto.Sha3(ethutil.NewValue(data).Encode())
O
obscuren 已提交
53 54
}

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
func (self *Transaction) Data() []byte {
	return self.data
}

func (self *Transaction) Gas() *big.Int {
	return self.gas
}

func (self *Transaction) GasPrice() *big.Int {
	return self.gasPrice
}

func (self *Transaction) Value() *big.Int {
	return self.value
}

func (self *Transaction) Nonce() uint64 {
	return self.nonce
}

func (self *Transaction) SetNonce(nonce uint64) {
	self.nonce = nonce
}

func (self *Transaction) From() []byte {
	return self.Sender()
}

func (self *Transaction) To() []byte {
	return self.recipient
}

O
obscuren 已提交
87 88 89 90 91 92 93 94
func (tx *Transaction) Curve() (v byte, r []byte, s []byte) {
	v = tx.v
	r = ethutil.LeftPadBytes(tx.r, 32)
	s = ethutil.LeftPadBytes(tx.s, 32)

	return
}

O
obscuren 已提交
95 96 97 98 99 100 101 102 103 104 105
func (tx *Transaction) Signature(key []byte) []byte {
	hash := tx.Hash()

	sig, _ := secp256k1.Sign(hash, key)

	return sig
}

func (tx *Transaction) PublicKey() []byte {
	hash := tx.Hash()

O
obscuren 已提交
106
	v, r, s := tx.Curve()
O
obscuren 已提交
107

108
	sig := append(r, s...)
O
obscuren 已提交
109
	sig = append(sig, v-27)
O
obscuren 已提交
110

O
obscuren 已提交
111
	pubkey := crypto.Ecrecover(append(hash, sig...))
O
obscuren 已提交
112
	//pubkey, _ := secp256k1.RecoverPubkey(hash, sig)
O
obscuren 已提交
113 114 115 116 117 118 119 120 121

	return pubkey
}

func (tx *Transaction) Sender() []byte {
	pubkey := tx.PublicKey()

	// Validate the returned key.
	// Return nil if public key isn't in full format
122
	if len(pubkey) != 0 && pubkey[0] != 4 {
O
obscuren 已提交
123 124 125
		return nil
	}

O
obscuren 已提交
126
	return crypto.Sha3(pubkey[1:])[12:]
O
obscuren 已提交
127 128 129 130 131 132 133 134 135 136 137 138 139 140
}

func (tx *Transaction) Sign(privk []byte) error {

	sig := tx.Signature(privk)

	tx.r = sig[:32]
	tx.s = sig[32:64]
	tx.v = sig[64] + 27

	return nil
}

func (tx *Transaction) RlpData() interface{} {
141
	data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.recipient, tx.Value, tx.Data}
O
obscuren 已提交
142

143 144
	// TODO Remove prefixing zero's

145
	return append(data, tx.v, new(big.Int).SetBytes(tx.r).Bytes(), new(big.Int).SetBytes(tx.s).Bytes())
O
obscuren 已提交
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
}

func (tx *Transaction) RlpValue() *ethutil.Value {
	return ethutil.NewValue(tx.RlpData())
}

func (tx *Transaction) RlpEncode() []byte {
	return tx.RlpValue().Encode()
}

func (tx *Transaction) RlpDecode(data []byte) {
	tx.RlpValueDecode(ethutil.NewValueFromBytes(data))
}

func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
161 162 163 164 165 166
	tx.nonce = decoder.Get(0).Uint()
	tx.gasPrice = decoder.Get(1).BigInt()
	tx.gas = decoder.Get(2).BigInt()
	tx.recipient = decoder.Get(3).Bytes()
	tx.value = decoder.Get(4).BigInt()
	tx.data = decoder.Get(5).Bytes()
O
obscuren 已提交
167
	tx.v = byte(decoder.Get(6).Uint())
O
obscuren 已提交
168

169 170
	tx.r = decoder.Get(7).Bytes()
	tx.s = decoder.Get(8).Bytes()
O
obscuren 已提交
171 172 173 174 175 176 177
}

func (tx *Transaction) String() string {
	return fmt.Sprintf(`
	TX(%x)
	Contract: %v
	From:     %x
O
obscuren 已提交
178
	To:       %x
O
obscuren 已提交
179 180 181 182 183 184 185 186 187 188
	Nonce:    %v
	GasPrice: %v
	Gas:      %v
	Value:    %v
	Data:     0x%x
	V:        0x%x
	R:        0x%x
	S:        0x%x
	`,
		tx.Hash(),
189
		len(tx.recipient) == 0,
190
		tx.Sender(),
191 192 193 194
		tx.recipient,
		tx.nonce,
		tx.gasPrice,
		tx.gas,
O
obscuren 已提交
195 196 197 198 199 200 201
		tx.Value,
		tx.Data,
		tx.v,
		tx.r,
		tx.s)
}

O
obscuren 已提交
202 203 204
// Transaction slice type for basic sorting
type Transactions []*Transaction

O
obscuren 已提交
205 206 207 208 209 210 211 212 213 214 215 216 217
func (self Transactions) RlpData() interface{} {
	// Marshal the transactions of this block
	enc := make([]interface{}, len(self))
	for i, tx := range self {
		// Cast it to a string (safe)
		enc[i] = tx.RlpData()
	}

	return enc
}
func (s Transactions) Len() int            { return len(s) }
func (s Transactions) Swap(i, j int)       { s[i], s[j] = s[j], s[i] }
func (s Transactions) GetRlp(i int) []byte { return ethutil.Rlp(s[i]) }
O
obscuren 已提交
218 219 220 221

type TxByNonce struct{ Transactions }

func (s TxByNonce) Less(i, j int) bool {
222
	return s.Transactions[i].nonce < s.Transactions[j].nonce
O
obscuren 已提交
223
}