2013-12-26 05:45:52 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/big"
|
|
|
|
"fmt"
|
2014-01-02 17:43:49 -06:00
|
|
|
_"encoding/hex"
|
|
|
|
_"crypto/sha256"
|
2013-12-26 05:45:52 -06:00
|
|
|
_ "bytes"
|
|
|
|
)
|
|
|
|
|
|
|
|
/*
|
|
|
|
Transaction Contract Size
|
|
|
|
-------------------------------------------
|
|
|
|
sender sender 20 bytes
|
|
|
|
recipient 0x0 20 bytes
|
|
|
|
value endowment 4 bytes (uint32)
|
|
|
|
fee fee 4 bytes (uint32)
|
|
|
|
d_size o_size 4 bytes (uint32)
|
|
|
|
data ops *
|
|
|
|
signature signature 64 bytes
|
|
|
|
*/
|
|
|
|
|
2013-12-27 05:07:37 -06:00
|
|
|
var StepFee *big.Int = new(big.Int)
|
|
|
|
var TxFee *big.Int = new(big.Int)
|
|
|
|
var ContractFee *big.Int = new(big.Int)
|
|
|
|
var MemFee *big.Int = new(big.Int)
|
|
|
|
var DataFee *big.Int = new(big.Int)
|
|
|
|
var CryptoFee *big.Int = new(big.Int)
|
|
|
|
var ExtroFee *big.Int = new(big.Int)
|
2013-12-26 05:45:52 -06:00
|
|
|
|
|
|
|
var Period1Reward *big.Int = new(big.Int)
|
|
|
|
var Period2Reward *big.Int = new(big.Int)
|
|
|
|
var Period3Reward *big.Int = new(big.Int)
|
|
|
|
var Period4Reward *big.Int = new(big.Int)
|
|
|
|
|
|
|
|
type Transaction struct {
|
|
|
|
sender string
|
2013-12-27 19:22:42 -06:00
|
|
|
recipient string
|
2013-12-26 05:45:52 -06:00
|
|
|
value uint32
|
|
|
|
fee uint32
|
|
|
|
data []string
|
|
|
|
memory []int
|
2013-12-27 19:22:42 -06:00
|
|
|
lastTx string
|
2013-12-26 05:45:52 -06:00
|
|
|
|
2013-12-27 14:23:40 -06:00
|
|
|
// To be removed
|
|
|
|
signature string
|
2013-12-26 05:45:52 -06:00
|
|
|
addr string
|
|
|
|
}
|
|
|
|
|
2013-12-27 19:22:42 -06:00
|
|
|
func NewTransaction(to string, value uint32, data []string) *Transaction {
|
2013-12-26 05:45:52 -06:00
|
|
|
tx := Transaction{sender: "1234567890", recipient: to, value: value}
|
|
|
|
tx.fee = 0//uint32((ContractFee + MemoryFee * float32(len(tx.data))) * 1e8)
|
2013-12-27 19:22:42 -06:00
|
|
|
tx.lastTx = "0"
|
2013-12-26 05:45:52 -06:00
|
|
|
|
|
|
|
// Serialize the data
|
|
|
|
tx.data = make([]string, len(data))
|
|
|
|
for i, val := range data {
|
|
|
|
instr, err := CompileInstr(val)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("compile error:%d %v", i+1, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tx.data[i] = instr
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return &tx
|
|
|
|
}
|
|
|
|
|
2014-01-02 17:43:49 -06:00
|
|
|
func (tx *Transaction) Hash() []byte {
|
|
|
|
return Sha256Bin(tx.MarshalRlp())
|
|
|
|
}
|
|
|
|
|
2013-12-27 14:23:40 -06:00
|
|
|
func (tx *Transaction) MarshalRlp() []byte {
|
2013-12-26 05:45:52 -06:00
|
|
|
// Prepare the transaction for serialization
|
|
|
|
preEnc := []interface{}{
|
2013-12-27 19:22:42 -06:00
|
|
|
tx.lastTx,
|
2013-12-26 05:45:52 -06:00
|
|
|
tx.sender,
|
2013-12-27 19:22:42 -06:00
|
|
|
tx.recipient,
|
|
|
|
tx.value,
|
|
|
|
tx.fee,
|
2013-12-26 05:45:52 -06:00
|
|
|
tx.data,
|
|
|
|
}
|
|
|
|
|
2013-12-28 08:18:08 -06:00
|
|
|
return Encode(preEnc)
|
2013-12-27 19:22:42 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (tx *Transaction) UnmarshalRlp(data []byte) {
|
|
|
|
t, _ := Decode(data,0)
|
|
|
|
if slice, ok := t.([]interface{}); ok {
|
|
|
|
if lastTx, ok := slice[0].([]byte); ok {
|
|
|
|
tx.lastTx = string(lastTx)
|
|
|
|
}
|
|
|
|
|
|
|
|
if sender, ok := slice[1].([]byte); ok {
|
|
|
|
tx.sender = string(sender)
|
|
|
|
}
|
|
|
|
|
|
|
|
if recipient, ok := slice[2].([]byte); ok {
|
|
|
|
tx.recipient = string(recipient)
|
|
|
|
}
|
|
|
|
|
|
|
|
// If only I knew of a better way.
|
|
|
|
if value, ok := slice[3].(uint8); ok {
|
|
|
|
tx.value = uint32(value)
|
|
|
|
}
|
|
|
|
if value, ok := slice[3].(uint16); ok {
|
|
|
|
tx.value = uint32(value)
|
|
|
|
}
|
|
|
|
if value, ok := slice[3].(uint32); ok {
|
|
|
|
tx.value = uint32(value)
|
|
|
|
}
|
|
|
|
if value, ok := slice[3].(uint64); ok {
|
|
|
|
tx.value = uint32(value)
|
|
|
|
}
|
|
|
|
if fee, ok := slice[4].(uint8); ok {
|
|
|
|
tx.fee = uint32(fee)
|
|
|
|
}
|
|
|
|
if fee, ok := slice[4].(uint16); ok {
|
|
|
|
tx.fee = uint32(fee)
|
|
|
|
}
|
|
|
|
if fee, ok := slice[4].(uint32); ok {
|
|
|
|
tx.fee = uint32(fee)
|
|
|
|
}
|
|
|
|
if fee, ok := slice[4].(uint64); ok {
|
|
|
|
tx.fee = uint32(fee)
|
|
|
|
}
|
|
|
|
|
2013-12-28 18:36:59 -06:00
|
|
|
// Encode the data/instructions
|
2013-12-27 19:22:42 -06:00
|
|
|
if data, ok := slice[5].([]interface{}); ok {
|
|
|
|
tx.data = make([]string, len(data))
|
|
|
|
for i, d := range data {
|
|
|
|
if instr, ok := d.([]byte); ok {
|
|
|
|
tx.data[i] = string(instr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-12-26 05:45:52 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func InitFees() {
|
|
|
|
// Base for 2**60
|
|
|
|
b60 := new(big.Int)
|
2013-12-27 05:07:37 -06:00
|
|
|
b60.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0))
|
2013-12-26 05:45:52 -06:00
|
|
|
// Base for 2**80
|
|
|
|
b80 := new(big.Int)
|
|
|
|
b80.Exp(big.NewInt(2), big.NewInt(80), big.NewInt(0))
|
|
|
|
|
2013-12-27 05:07:37 -06:00
|
|
|
StepFee.Div(b60, big.NewInt(64))
|
2013-12-26 05:45:52 -06:00
|
|
|
//fmt.Println("StepFee:", StepFee)
|
|
|
|
|
2013-12-27 05:07:37 -06:00
|
|
|
TxFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0))
|
2013-12-26 05:45:52 -06:00
|
|
|
//fmt.Println("TxFee:", TxFee)
|
|
|
|
|
2013-12-27 05:07:37 -06:00
|
|
|
ContractFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0))
|
|
|
|
//fmt.Println("ContractFee:", ContractFee)
|
|
|
|
|
|
|
|
MemFee.Div(b60, big.NewInt(4))
|
2013-12-26 05:45:52 -06:00
|
|
|
//fmt.Println("MemFee:", MemFee)
|
|
|
|
|
2013-12-27 05:07:37 -06:00
|
|
|
DataFee.Div(b60, big.NewInt(16))
|
2013-12-26 05:45:52 -06:00
|
|
|
//fmt.Println("DataFee:", DataFee)
|
|
|
|
|
2013-12-27 05:07:37 -06:00
|
|
|
CryptoFee.Div(b60, big.NewInt(16))
|
2013-12-26 05:45:52 -06:00
|
|
|
//fmt.Println("CrytoFee:", CryptoFee)
|
|
|
|
|
2013-12-27 05:07:37 -06:00
|
|
|
ExtroFee.Div(b60, big.NewInt(16))
|
2013-12-26 05:45:52 -06:00
|
|
|
//fmt.Println("ExtroFee:", ExtroFee)
|
|
|
|
|
|
|
|
Period1Reward.Mul(b80, big.NewInt(1024))
|
|
|
|
//fmt.Println("Period1Reward:", Period1Reward)
|
|
|
|
|
|
|
|
Period2Reward.Mul(b80, big.NewInt(512))
|
|
|
|
//fmt.Println("Period2Reward:", Period2Reward)
|
|
|
|
|
|
|
|
Period3Reward.Mul(b80, big.NewInt(256))
|
|
|
|
//fmt.Println("Period3Reward:", Period3Reward)
|
|
|
|
|
|
|
|
Period4Reward.Mul(b80, big.NewInt(128))
|
|
|
|
//fmt.Println("Period4Reward:", Period4Reward)
|
|
|
|
}
|