Merge basecoin with tendermint_classic
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
type Account struct {
|
||||
PubKey crypto.PubKey // May be nil, if not known.
|
||||
Sequence int
|
||||
Balance int64
|
||||
}
|
||||
|
||||
func (acc *Account) Copy() *Account {
|
||||
accCopy := *acc
|
||||
return &accCopy
|
||||
}
|
||||
|
||||
func (acc *Account) String() string {
|
||||
if acc == nil {
|
||||
return "nil-Account"
|
||||
}
|
||||
return fmt.Sprintf("Account{%v %v %v}",
|
||||
acc.PubKey, acc.Sequence, acc.Balance)
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
type PrivAccount struct {
|
||||
crypto.PrivKey
|
||||
Account
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
type AccountGetter interface {
|
||||
GetAccount(addr []byte) *Account
|
||||
}
|
||||
|
||||
type AccountGetterSetter interface {
|
||||
GetAccount(addr []byte) *Account
|
||||
SetAccount(acc *Account)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
tmsp "github.com/tendermint/tmsp/types"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrDuplicateAddress = tmsp.NewError(tmsp.CodeType_BaseDuplicateAddress, "Error duplicate address")
|
||||
ErrEncodingError = tmsp.NewError(tmsp.CodeType_BaseEncodingError, "Error encoding error")
|
||||
ErrInsufficientFees = tmsp.NewError(tmsp.CodeType_BaseInsufficientFees, "Error insufficient fees")
|
||||
ErrInsufficientFunds = tmsp.NewError(tmsp.CodeType_BaseInsufficientFunds, "Error insufficient funds")
|
||||
ErrInsufficientGasPrice = tmsp.NewError(tmsp.CodeType_BaseInsufficientGasPrice, "Error insufficient gas price")
|
||||
ErrInvalidAddress = tmsp.NewError(tmsp.CodeType_BaseInvalidAddress, "Error invalid address")
|
||||
ErrInvalidAmount = tmsp.NewError(tmsp.CodeType_BaseInvalidAmount, "Error invalid amount")
|
||||
ErrInvalidPubKey = tmsp.NewError(tmsp.CodeType_BaseInvalidPubKey, "Error invalid pubkey")
|
||||
ErrInvalidSequence = tmsp.NewError(tmsp.CodeType_BaseInvalidSequence, "Error invalid sequence")
|
||||
ErrInvalidSignature = tmsp.NewError(tmsp.CodeType_BaseInvalidSignature, "Error invalid signature")
|
||||
ErrUnknownPubKey = tmsp.NewError(tmsp.CodeType_BaseUnknownPubKey, "Error unknown pubkey")
|
||||
|
||||
ResultOK = tmsp.NewResultOK(nil, "")
|
||||
)
|
||||
@@ -0,0 +1,6 @@
|
||||
package types
|
||||
|
||||
type Plugin func(ags AccountGetterSetter,
|
||||
caller *Account,
|
||||
input []byte,
|
||||
gas *int64) (result []byte, err error)
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire"
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
||||
/*
|
||||
Tx (Transaction) is an atomic operation on the ledger state.
|
||||
|
||||
Account Types:
|
||||
- SendTx Send coins to address
|
||||
- CallTx Send a msg to a contract that runs in the vm
|
||||
*/
|
||||
|
||||
type Tx interface {
|
||||
SignBytes(chainID string) []byte
|
||||
}
|
||||
|
||||
// Types of Tx implementations
|
||||
const (
|
||||
// Account transactions
|
||||
TxTypeSend = byte(0x01)
|
||||
TxTypeCall = byte(0x02)
|
||||
)
|
||||
|
||||
var _ = wire.RegisterInterface(
|
||||
struct{ Tx }{},
|
||||
wire.ConcreteType{&SendTx{}, TxTypeSend},
|
||||
wire.ConcreteType{&CallTx{}, TxTypeCall},
|
||||
)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type TxInput struct {
|
||||
Address []byte `json:"address"` // Hash of the PubKey
|
||||
Amount int64 `json:"amount"` // Must not exceed account balance
|
||||
Sequence int `json:"sequence"` // Must be 1 greater than the last committed TxInput
|
||||
Signature crypto.Signature `json:"signature"` // Depends on the PubKey type and the whole Tx
|
||||
PubKey crypto.PubKey `json:"pub_key"` // May be nil
|
||||
}
|
||||
|
||||
func (txIn TxInput) ValidateBasic() error {
|
||||
if len(txIn.Address) != 20 {
|
||||
return ErrInvalidAddress
|
||||
}
|
||||
if txIn.Amount == 0 {
|
||||
return ErrInvalidAmount
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txIn TxInput) SignBytes() []byte {
|
||||
return []byte(Fmt(`{"address":"%X","amount":%v,"sequence":%v}`,
|
||||
txIn.Address, txIn.Amount, txIn.Sequence))
|
||||
}
|
||||
|
||||
func (txIn TxInput) String() string {
|
||||
return Fmt("TxInput{%X,%v,%v,%v,%v}", txIn.Address, txIn.Amount, txIn.Sequence, txIn.Signature, txIn.PubKey)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type TxOutput struct {
|
||||
Address []byte `json:"address"` // Hash of the PubKey
|
||||
Amount int64 `json:"amount"` // The sum of all outputs must not exceed the inputs.
|
||||
}
|
||||
|
||||
func (txOut TxOutput) ValidateBasic() error {
|
||||
if len(txOut.Address) != 20 {
|
||||
return ErrInvalidAddress
|
||||
}
|
||||
if txOut.Amount == 0 {
|
||||
return ErrInvalidAmount
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txOut TxOutput) SignBytes() []byte {
|
||||
return []byte(Fmt(`{"address":"%X","amount":%v}`,
|
||||
txOut.Address, txOut.Amount))
|
||||
}
|
||||
|
||||
func (txOut TxOutput) String() string {
|
||||
return Fmt("TxOutput{%X,%v}", txOut.Address, txOut.Amount)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type SendTx struct {
|
||||
Inputs []TxInput `json:"inputs"`
|
||||
Outputs []TxOutput `json:"outputs"`
|
||||
}
|
||||
|
||||
func (tx *SendTx) SignBytes(chainID string) []byte {
|
||||
var buf = new(bytes.Buffer)
|
||||
buf.Write([]byte(Fmt(`{"chain_id":%s`, jsonEscape(chainID))))
|
||||
buf.Write([]byte(Fmt(`,"tx":[%v,{"inputs":[`, TxTypeSend)))
|
||||
for i, in := range tx.Inputs {
|
||||
buf.Write(in.SignBytes())
|
||||
if i != len(tx.Inputs)-1 {
|
||||
buf.Write([]byte(","))
|
||||
}
|
||||
}
|
||||
buf.Write([]byte(`],"outputs":[`))
|
||||
for i, out := range tx.Outputs {
|
||||
buf.Write(out.SignBytes())
|
||||
if i != len(tx.Outputs)-1 {
|
||||
buf.Write([]byte(","))
|
||||
}
|
||||
}
|
||||
buf.Write([]byte(`]}]}`))
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func (tx *SendTx) String() string {
|
||||
return Fmt("SendTx{%v -> %v}", tx.Inputs, tx.Outputs)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type CallTx struct {
|
||||
Input TxInput `json:"input"`
|
||||
Address []byte `json:"address"`
|
||||
GasLimit int64 `json:"gas_limit"`
|
||||
Fee int64 `json:"fee"`
|
||||
Data []byte `json:"data"`
|
||||
}
|
||||
|
||||
func (tx *CallTx) SignBytes(chainID string) []byte {
|
||||
var buf = new(bytes.Buffer)
|
||||
buf.Write([]byte(Fmt(`{"chain_id":%s`, jsonEscape(chainID))))
|
||||
buf.Write([]byte(Fmt(`,"tx":[%v,{"address":"%X","data":"%X"`, TxTypeCall, tx.Address, tx.Data)))
|
||||
buf.Write([]byte(Fmt(`,"fee":%v,"gas_limit":%v,"input":`, tx.Fee, tx.GasLimit)))
|
||||
buf.Write(tx.Input.SignBytes())
|
||||
buf.Write([]byte(`}]}`))
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func (tx *CallTx) String() string {
|
||||
return Fmt("CallTx{%v -> %x: %x}", tx.Input, tx.Address, tx.Data)
|
||||
}
|
||||
|
||||
func NewContractAddress(caller []byte, nonce int) []byte {
|
||||
temp := make([]byte, 32+8)
|
||||
copy(temp, caller)
|
||||
PutInt64BE(temp[32:], int64(nonce))
|
||||
hasher := ripemd160.New()
|
||||
hasher.Write(temp) // does not error
|
||||
return hasher.Sum(nil)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
func TxID(chainID string, tx Tx) []byte {
|
||||
signBytes := tx.SignBytes(chainID)
|
||||
return wire.BinaryRipemd160(signBytes)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
// Contract: This function is deterministic and completely reversible.
|
||||
func jsonEscape(str string) string {
|
||||
escapedBytes, err := json.Marshal(str)
|
||||
if err != nil {
|
||||
PanicSanity(Fmt("Error json-escaping a string", str))
|
||||
}
|
||||
return string(escapedBytes)
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
var chainID string = "test_chain"
|
||||
|
||||
func TestSendTxSignable(t *testing.T) {
|
||||
sendTx := &SendTx{
|
||||
Inputs: []TxInput{
|
||||
TxInput{
|
||||
Address: []byte("input1"),
|
||||
Amount: 12345,
|
||||
Sequence: 67890,
|
||||
},
|
||||
TxInput{
|
||||
Address: []byte("input2"),
|
||||
Amount: 111,
|
||||
Sequence: 222,
|
||||
},
|
||||
},
|
||||
Outputs: []TxOutput{
|
||||
TxOutput{
|
||||
Address: []byte("output1"),
|
||||
Amount: 333,
|
||||
},
|
||||
TxOutput{
|
||||
Address: []byte("output2"),
|
||||
Amount: 444,
|
||||
},
|
||||
},
|
||||
}
|
||||
signBytes := sendTx.SignBytes(chainID)
|
||||
signStr := string(signBytes)
|
||||
expected := Fmt(`{"chain_id":"%s","tx":[1,{"inputs":[{"address":"696E70757431","amount":12345,"sequence":67890},{"address":"696E70757432","amount":111,"sequence":222}],"outputs":[{"address":"6F757470757431","amount":333},{"address":"6F757470757432","amount":444}]}]}`,
|
||||
chainID)
|
||||
if signStr != expected {
|
||||
t.Errorf("Got unexpected sign string for SendTx. Expected:\n%v\nGot:\n%v", expected, signStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallTxSignable(t *testing.T) {
|
||||
callTx := &CallTx{
|
||||
Input: TxInput{
|
||||
Address: []byte("input1"),
|
||||
Amount: 12345,
|
||||
Sequence: 67890,
|
||||
},
|
||||
Address: []byte("contract1"),
|
||||
GasLimit: 111,
|
||||
Fee: 222,
|
||||
Data: []byte("data1"),
|
||||
}
|
||||
signBytes := callTx.SignBytes(chainID)
|
||||
signStr := string(signBytes)
|
||||
expected := Fmt(`{"chain_id":"%s","tx":[2,{"address":"636F6E747261637431","data":"6461746131","fee":222,"gas_limit":111,"input":{"address":"696E70757431","amount":12345,"sequence":67890}}]}`,
|
||||
chainID)
|
||||
if signStr != expected {
|
||||
t.Errorf("Got unexpected sign string for CallTx. Expected:\n%v\nGot:\n%v", expected, signStr)
|
||||
}
|
||||
}
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire"
|
||||
gov "github.com/tendermint/governmint/types"
|
||||
)
|
||||
|
||||
type Input struct {
|
||||
PubKey crypto.PubKey
|
||||
Amount uint64
|
||||
Sequence uint
|
||||
Signature crypto.Signature
|
||||
}
|
||||
|
||||
type Output struct {
|
||||
PubKey crypto.PubKey
|
||||
Amount uint64
|
||||
}
|
||||
|
||||
type SendTx struct {
|
||||
Inputs []Input
|
||||
Outputs []Output
|
||||
}
|
||||
|
||||
func (tx *SendTx) SignBytes() []byte {
|
||||
sigs := make([]crypto.Signature, len(tx.Inputs))
|
||||
for i, input := range tx.Inputs {
|
||||
sigs[i] = input.Signature
|
||||
input.Signature = nil
|
||||
tx.Inputs[i] = input
|
||||
}
|
||||
signBytes := wire.BinaryBytes(tx)
|
||||
for i := range tx.Inputs {
|
||||
tx.Inputs[i].Signature = sigs[i]
|
||||
}
|
||||
return signBytes
|
||||
}
|
||||
|
||||
func (tx *SendTx) GetInputs() []Input { return tx.Inputs }
|
||||
func (tx *SendTx) GetOutputs() []Output { return tx.Outputs }
|
||||
|
||||
type GovTx struct {
|
||||
Input Input
|
||||
Tx gov.Tx
|
||||
}
|
||||
|
||||
func (tx *GovTx) SignBytes() []byte {
|
||||
sig := tx.Input.Signature
|
||||
tx.Input.Signature = nil
|
||||
signBytes := wire.BinaryBytes(tx)
|
||||
tx.Input.Signature = sig
|
||||
return signBytes
|
||||
}
|
||||
|
||||
func (tx *GovTx) GetInputs() []Input { return []Input{tx.Input} }
|
||||
func (tx *GovTx) GetOutputs() []Output { return nil }
|
||||
|
||||
type Tx interface {
|
||||
AssertIsTx()
|
||||
SignBytes() []byte
|
||||
GetInputs() []Input
|
||||
GetOutputs() []Output
|
||||
}
|
||||
|
||||
func (_ *SendTx) AssertIsTx() {}
|
||||
func (_ *GovTx) AssertIsTx() {}
|
||||
|
||||
const (
|
||||
TxTypeSend = byte(0x01)
|
||||
TxTypeGov = byte(0x02)
|
||||
)
|
||||
|
||||
var _ = wire.RegisterInterface(
|
||||
struct{ Tx }{},
|
||||
wire.ConcreteType{&SendTx{}, TxTypeSend},
|
||||
wire.ConcreteType{&GovTx{}, TxTypeGov},
|
||||
)
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
type Account struct {
|
||||
Sequence uint
|
||||
Balance uint64
|
||||
}
|
||||
|
||||
type PubAccount struct {
|
||||
crypto.PubKey
|
||||
Account
|
||||
}
|
||||
|
||||
type PrivAccount struct {
|
||||
crypto.PubKey
|
||||
crypto.PrivKey
|
||||
Account
|
||||
}
|
||||
|
||||
type GenesisState struct {
|
||||
Accounts []PubAccount
|
||||
}
|
||||
Reference in New Issue
Block a user