OSDN Git Service

Coinbase input (#290)
authorPaladz <yzhu101@uottawa.ca>
Tue, 16 Jan 2018 11:40:08 +0000 (19:40 +0800)
committerGitHub <noreply@github.com>
Tue, 16 Jan 2018 11:40:08 +0000 (19:40 +0800)
* init push for coinbase have input

* fix io write bug

* support wallet display

* fix map side bug

17 files changed:
blockchain/query/annotated.go
blockchain/txbuilder/builder.go
blockchain/wallet/annotated.go
config/genesis.go
mining/mining.go
protocol/bc/bc.pb.go
protocol/bc/bc.proto
protocol/bc/coinbase.go
protocol/bc/legacy/coinbase.go [new file with mode: 0644]
protocol/bc/legacy/issuance.go
protocol/bc/legacy/map.go
protocol/bc/legacy/map_test.go
protocol/bc/legacy/spend.go
protocol/bc/legacy/transaction.go
protocol/bc/legacy/transaction_test.go
protocol/bc/legacy/txinput.go
protocol/validation/validation_test.go

index 7533a27..a84c8b9 100755 (executable)
@@ -37,6 +37,7 @@ type AnnotatedInput struct {
        AccountAlias    string             `json:"account_alias,omitempty"`
        AccountTags     *json.RawMessage   `json:"account_tags,omitempty"`
        ReferenceData   *json.RawMessage   `json:"reference_data"`
+       Arbitrary       chainjson.HexBytes `json:"arbitrary,omitempty"`
 }
 
 //AnnotatedOutput means an annotated transaction output.
index 5cdb8dc..d86ed21 100755 (executable)
@@ -26,7 +26,7 @@ type TemplateBuilder struct {
 }
 
 func (b *TemplateBuilder) AddInput(in *legacy.TxInput, sigInstruction *SigningInstruction) error {
-       if in.Amount() > math.MaxInt64 {
+       if !in.IsCoinbase() && in.Amount() > math.MaxInt64 {
                return errors.WithDetailf(ErrBadAmount, "amount %d exceeds maximum value 2^63", in.Amount())
        }
        b.inputs = append(b.inputs, in)
index 66d5251..1a451a8 100755 (executable)
@@ -167,12 +167,14 @@ func buildAnnotatedTransaction(orig *legacy.Tx, b *legacy.Block, indexInBlock ui
 func buildAnnotatedInput(tx *legacy.Tx, i uint32) *query.AnnotatedInput {
        orig := tx.Inputs[i]
        in := &query.AnnotatedInput{
-               AssetID:         orig.AssetID(),
-               Amount:          orig.Amount(),
                AssetDefinition: &emptyJSONObject,
                AssetTags:       &emptyJSONObject,
                ReferenceData:   &emptyJSONObject,
        }
+       if !orig.IsCoinbase() {
+               in.AssetID = orig.AssetID()
+               in.Amount = orig.Amount()
+       }
        if isValidJSON(orig.ReferenceData) {
                referenceData := json.RawMessage(orig.ReferenceData)
                in.ReferenceData = &referenceData
@@ -188,8 +190,10 @@ func buildAnnotatedInput(tx *legacy.Tx, i uint32) *query.AnnotatedInput {
        case *bc.Issuance:
                in.Type = "issue"
                in.IssuanceProgram = orig.IssuanceProgram()
+       case *bc.Coinbase:
+               in.Type = "coinbase"
+               in.Arbitrary = e.Arbitrary
        }
-
        return in
 }
 
index febb23b..2658660 100644 (file)
@@ -15,7 +15,9 @@ func GenerateGenesisTx() *legacy.Tx {
        txData := legacy.TxData{
                Version:        1,
                SerializedSize: 63,
-               Inputs:         []*legacy.TxInput{},
+               Inputs: []*legacy.TxInput{
+                       legacy.NewCoinbaseInput([]byte("May 4th Be With You"), nil),
+               },
                Outputs: []*legacy.TxOutput{
                        &legacy.TxOutput{
                                AssetVersion: 1,
@@ -49,7 +51,7 @@ func GenerateGenesisBlock() *legacy.Block {
                BlockHeader: legacy.BlockHeader{
                        Version:     1,
                        Height:      0,
-                       Nonce:       1267808,
+                       Nonce:       1523829,
                        Seed:        bc.NewHash(seed),
                        TimestampMS: 1511318565142,
                        BlockCommitment: legacy.BlockCommitment{
index ab2c934..ef78ce0 100644 (file)
@@ -41,7 +41,12 @@ func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeigh
        }
 
        builder := txbuilder.NewBuilder(time.Now())
-       builder.AddOutput(legacy.NewTxOutput(*consensus.BTMAssetID, amount, script, nil))
+       if err = builder.AddInput(legacy.NewCoinbaseInput([]byte(string(blockHeight)), nil), &txbuilder.SigningInstruction{}); err != nil {
+               return
+       }
+       if err = builder.AddOutput(legacy.NewTxOutput(*consensus.BTMAssetID, amount, script, nil)); err != nil {
+               return
+       }
        _, txData, err := builder.Build()
        if err != nil {
                return
index 705a872..2e2a92d 100644 (file)
@@ -497,6 +497,7 @@ func (m *Nonce) GetWitnessAnchoredId() *Hash {
 
 type Coinbase struct {
        WitnessDestination *ValueDestination `protobuf:"bytes,1,opt,name=witness_destination,json=witnessDestination" json:"witness_destination,omitempty"`
+       Arbitrary          []byte            `protobuf:"bytes,2,opt,name=arbitrary,proto3" json:"arbitrary,omitempty"`
 }
 
 func (m *Coinbase) Reset()                    { *m = Coinbase{} }
@@ -511,6 +512,13 @@ func (m *Coinbase) GetWitnessDestination() *ValueDestination {
        return nil
 }
 
+func (m *Coinbase) GetArbitrary() []byte {
+       if m != nil {
+               return m.Arbitrary
+       }
+       return nil
+}
+
 type Output struct {
        Source         *ValueSource `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"`
        ControlProgram *Program     `protobuf:"bytes,2,opt,name=control_program,json=controlProgram" json:"control_program,omitempty"`
@@ -765,63 +773,64 @@ func init() {
 func init() { proto.RegisterFile("bc.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-       // 928 bytes of a gzipped FileDescriptorProto
-       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x6e, 0xe3, 0x44,
-       0x14, 0x96, 0x63, 0x27, 0x76, 0x4e, 0x4a, 0x93, 0x4e, 0xab, 0x95, 0xb5, 0x5a, 0xa4, 0x62, 0x54,
-       0xba, 0x2b, 0xa4, 0xaa, 0x9b, 0x2e, 0x88, 0x0b, 0x6e, 0x0a, 0x05, 0x36, 0x17, 0xe5, 0xc7, 0x45,
-       0x7b, 0x6b, 0x4d, 0xec, 0xd9, 0x66, 0x44, 0xe2, 0x09, 0x33, 0xe3, 0x50, 0xf5, 0x31, 0xb8, 0xe5,
-       0x2d, 0xb8, 0x83, 0xeb, 0x7d, 0x1b, 0xee, 0x78, 0x02, 0xe4, 0xe3, 0xb1, 0xf3, 0xe7, 0xec, 0x26,
-       0xda, 0x72, 0xe7, 0xf3, 0xe3, 0xf3, 0xf3, 0x9d, 0xf3, 0xcd, 0x0c, 0x78, 0xc3, 0xf8, 0x6c, 0x2a,
-       0x85, 0x16, 0xa4, 0x31, 0x8c, 0x83, 0x6f, 0xc1, 0x79, 0x49, 0xd5, 0x88, 0xec, 0x43, 0x63, 0x76,
-       0xee, 0x5b, 0xc7, 0xd6, 0xd3, 0x56, 0xd8, 0x98, 0x9d, 0xa3, 0xfc, 0xdc, 0x6f, 0x18, 0xf9, 0x39,
-       0xca, 0x7d, 0xdf, 0x36, 0x72, 0x1f, 0xe5, 0x0b, 0xdf, 0x31, 0xf2, 0x45, 0xf0, 0x25, 0xb8, 0x3f,
-       0x4a, 0x71, 0x2b, 0xe9, 0x84, 0x7c, 0x08, 0x30, 0x9b, 0x44, 0x33, 0x26, 0x15, 0x17, 0x29, 0x86,
-       0x74, 0xc2, 0xf6, 0x6c, 0xf2, 0xaa, 0x50, 0x10, 0x02, 0x4e, 0x2c, 0x12, 0x86, 0xb1, 0xf7, 0x42,
-       0xfc, 0x0e, 0x06, 0xe0, 0x5e, 0x2a, 0xc5, 0xf4, 0xe0, 0xea, 0xbd, 0x0b, 0xb9, 0x86, 0x0e, 0x86,
-       0xba, 0x9c, 0x88, 0x2c, 0xd5, 0xe4, 0x13, 0xf0, 0x68, 0x2e, 0x46, 0x3c, 0xc1, 0xa0, 0x9d, 0x7e,
-       0xe7, 0x6c, 0x18, 0x9f, 0x99, 0x6c, 0xa1, 0x8b, 0xc6, 0x41, 0x42, 0x1e, 0x41, 0x8b, 0xe2, 0x1f,
-       0x98, 0xca, 0x09, 0x8d, 0x14, 0xfc, 0x61, 0x41, 0x17, 0x9d, 0xaf, 0xd8, 0x6b, 0x9e, 0x72, 0x9d,
-       0x77, 0xd0, 0x87, 0x1e, 0x7e, 0xd2, 0x71, 0x34, 0x1c, 0x8b, 0xf8, 0x97, 0x79, 0x6c, 0x2f, 0x8f,
-       0x9d, 0xe3, 0x19, 0xee, 0x1b, 0x8f, 0xaf, 0x72, 0x87, 0x41, 0x42, 0x3e, 0x87, 0x1e, 0x57, 0x2a,
-       0xa3, 0x69, 0xcc, 0xa2, 0x69, 0x01, 0x14, 0x66, 0x32, 0xf5, 0x18, 0xec, 0xc2, 0x6e, 0xe9, 0x54,
-       0x82, 0xf9, 0x04, 0x9c, 0x84, 0x6a, 0x8a, 0x0d, 0x2f, 0xc6, 0x47, 0x6d, 0x30, 0x86, 0xce, 0x2b,
-       0x3a, 0xce, 0xd8, 0x8d, 0xc8, 0x64, 0xcc, 0xc8, 0x63, 0xb0, 0x25, 0x7b, 0xbd, 0x56, 0x4b, 0xae,
-       0x24, 0x27, 0xd0, 0x9c, 0xe5, 0xae, 0x26, 0x6b, 0xb7, 0x42, 0xa1, 0x00, 0x2a, 0x2c, 0xac, 0xe4,
-       0x31, 0x78, 0x53, 0xa1, 0xb0, 0x4f, 0xcc, 0xe9, 0x84, 0x95, 0x1c, 0xfc, 0x0a, 0x3d, 0xcc, 0x76,
-       0xc5, 0x94, 0xe6, 0x29, 0x45, 0x2c, 0xfe, 0xe7, 0x94, 0xff, 0x34, 0xa0, 0x83, 0x10, 0xbe, 0x64,
-       0x34, 0x61, 0x92, 0xf8, 0xe0, 0x2e, 0x2f, 0x56, 0x29, 0x92, 0x53, 0xe8, 0x2a, 0x26, 0x39, 0x1d,
-       0xf3, 0x7b, 0x96, 0x44, 0x8a, 0xdf, 0x33, 0x33, 0xc9, 0xfd, 0xb9, 0xfa, 0x86, 0xdf, 0xb3, 0x7c,
-       0xd2, 0x23, 0xc6, 0x6f, 0x47, 0xda, 0x24, 0x33, 0x12, 0x79, 0x01, 0x07, 0x53, 0xc9, 0x66, 0x5c,
-       0x64, 0x6a, 0x3e, 0x56, 0x67, 0xa5, 0xaf, 0x6e, 0xe9, 0x52, 0xce, 0xf5, 0x09, 0x38, 0x8a, 0xb1,
-       0xc4, 0x6f, 0xae, 0xce, 0x27, 0xd7, 0x92, 0x8f, 0x60, 0x4f, 0xf3, 0x09, 0x53, 0x9a, 0x4e, 0xa6,
-       0xd1, 0x44, 0xf9, 0x2d, 0xcc, 0xd8, 0xa9, 0x74, 0xd7, 0x8a, 0x7c, 0x06, 0x07, 0x5a, 0xd2, 0x54,
-       0xd1, 0x38, 0x6f, 0x58, 0x45, 0x52, 0x08, 0xed, 0xbb, 0x2b, 0xd1, 0x7a, 0x8b, 0x2e, 0xa1, 0x10,
-       0x9a, 0x3c, 0x83, 0x0e, 0xae, 0xae, 0xf9, 0xc1, 0x5b, 0xf9, 0x01, 0x0a, 0x23, 0xba, 0x1e, 0x41,
-       0x33, 0x15, 0x69, 0xcc, 0xfc, 0x36, 0x66, 0x2f, 0x84, 0x9c, 0x86, 0x43, 0xae, 0x95, 0x0f, 0xa8,
-       0xc4, 0xef, 0xe0, 0x2f, 0x0b, 0xbc, 0x9f, 0xef, 0x1e, 0x0e, 0xea, 0x53, 0x00, 0xc9, 0x54, 0x36,
-       0xce, 0xd9, 0xa7, 0x7c, 0xfb, 0xd8, 0x5e, 0xaa, 0xb1, 0x5d, 0xd8, 0x06, 0x89, 0xaa, 0xb6, 0xdc,
-       0xa9, 0xdb, 0x72, 0xf2, 0x31, 0x78, 0xec, 0x4e, 0x47, 0x23, 0xaa, 0x46, 0x6b, 0x38, 0xbb, 0xec,
-       0x4e, 0xe7, 0x1f, 0xc1, 0xbf, 0x16, 0xd8, 0xd7, 0xd9, 0x1d, 0x79, 0x06, 0xae, 0x42, 0x36, 0x28,
-       0xdf, 0xc2, 0x84, 0xb8, 0x76, 0x0b, 0x2c, 0x09, 0x4b, 0x3b, 0x39, 0x01, 0xf7, 0x2d, 0x54, 0x2c,
-       0x6d, 0x4b, 0xe9, 0xed, 0x0d, 0xe9, 0xc9, 0x77, 0x70, 0xf4, 0x1b, 0xd7, 0x29, 0x53, 0x2a, 0x4a,
-       0xe6, 0xf4, 0x50, 0xbe, 0x83, 0x35, 0x1c, 0x55, 0x35, 0x2c, 0x70, 0x27, 0x3c, 0x34, 0x7f, 0x2c,
-       0xe8, 0x14, 0xf9, 0x14, 0x0e, 0xca, 0x40, 0x54, 0xde, 0x66, 0x13, 0x96, 0x6a, 0xe5, 0x37, 0x8f,
-       0xed, 0xa7, 0x7b, 0x61, 0xcf, 0x18, 0x2e, 0x4b, 0x7d, 0xf0, 0xb7, 0x05, 0xcd, 0xef, 0x71, 0x9c,
-       0x0b, 0xbd, 0x58, 0x5b, 0xf6, 0xd2, 0xd8, 0xd4, 0x4b, 0x6d, 0x09, 0x76, 0x7d, 0x09, 0xe4, 0x0b,
-       0x38, 0xac, 0x9c, 0xd3, 0x78, 0x24, 0x24, 0x4b, 0xea, 0x88, 0x53, 0x46, 0xbc, 0x34, 0x3e, 0x83,
-       0x24, 0xf8, 0x09, 0xbc, 0xaf, 0x05, 0x4f, 0x87, 0x54, 0x31, 0xf2, 0xcd, 0x3c, 0xca, 0x02, 0x7c,
-       0xa6, 0x95, 0x7a, 0xf4, 0xc8, 0x3a, 0x7a, 0xc1, 0x1b, 0x0b, 0x5a, 0x3f, 0x64, 0x7a, 0x9a, 0x69,
-       0x72, 0x0a, 0xad, 0x62, 0xce, 0x26, 0xc8, 0xda, 0x1a, 0x18, 0x33, 0x79, 0x01, 0xdd, 0x58, 0xa4,
-       0x5a, 0x8a, 0xf1, 0xdb, 0x0e, 0xe6, 0x7d, 0xe3, 0xb3, 0xd5, 0xb9, 0xbc, 0x04, 0xb3, 0xb3, 0x09,
-       0x66, 0x1f, 0x5c, 0x21, 0x13, 0x9e, 0xd2, 0x31, 0x6e, 0xb5, 0x13, 0x96, 0x62, 0xf0, 0xbb, 0x05,
-       0x10, 0x32, 0xcd, 0x25, 0xcb, 0x31, 0xde, 0xbe, 0x95, 0xb2, 0xa8, 0xc6, 0x3b, 0x8b, 0xb2, 0xb7,
-       0x28, 0xca, 0x59, 0x2e, 0xea, 0x4f, 0x1b, 0xbc, 0x81, 0xb9, 0x9d, 0xc8, 0x09, 0xb4, 0x8b, 0x69,
-       0xd7, 0xdd, 0x7d, 0x5e, 0x61, 0x1a, 0x24, 0xdb, 0xde, 0x00, 0x0f, 0x00, 0xe6, 0x86, 0x05, 0x6a,
-       0xee, 0xb6, 0x40, 0xe4, 0x1a, 0xfc, 0x6a, 0x9b, 0xf1, 0xd9, 0x90, 0x54, 0xd7, 0x3e, 0x1e, 0xde,
-       0x9d, 0xfe, 0x61, 0xd5, 0xc3, 0xfc, 0x45, 0x10, 0x3e, 0x2a, 0xb7, 0x7b, 0xe5, 0xa5, 0x50, 0xcb,
-       0x24, 0x77, 0x37, 0x26, 0x79, 0xef, 0x64, 0xd2, 0xe2, 0xd0, 0xda, 0xcb, 0x43, 0x7b, 0xd3, 0x80,
-       0xe6, 0xcd, 0x94, 0xa5, 0x09, 0x39, 0x87, 0xae, 0x9a, 0xb2, 0x54, 0x47, 0x02, 0xf9, 0x51, 0x37,
-       0xb7, 0x0f, 0xd0, 0xa1, 0xe0, 0x4f, 0x71, 0xb5, 0xbd, 0xef, 0x36, 0x6d, 0x98, 0x8a, 0xb3, 0xe3,
-       0x54, 0x76, 0x39, 0x13, 0x37, 0xc1, 0xd8, 0xda, 0x09, 0x46, 0x77, 0x09, 0xc6, 0x61, 0x0b, 0x1f,
-       0xcc, 0x17, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x0f, 0x45, 0xae, 0x3c, 0x0b, 0x00, 0x00,
+       // 941 bytes of a gzipped FileDescriptorProto
+       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4f, 0x6f, 0xe3, 0x44,
+       0x14, 0x97, 0x63, 0x27, 0x76, 0x5e, 0x4a, 0x93, 0x4e, 0xab, 0x95, 0xb5, 0x2a, 0x52, 0x31, 0x2a,
+       0xdd, 0x15, 0x52, 0xd5, 0x4d, 0x17, 0xc4, 0x81, 0x4b, 0xa1, 0xc0, 0xe6, 0x50, 0x40, 0x2e, 0xda,
+       0xab, 0x35, 0xb1, 0x67, 0x9b, 0x11, 0x89, 0x27, 0xcc, 0x8c, 0x43, 0xe9, 0xc7, 0xe0, 0xca, 0xb7,
+       0xe0, 0x06, 0xe7, 0xfd, 0x36, 0xdc, 0xf8, 0x04, 0xc8, 0xcf, 0x63, 0xe7, 0x9f, 0xb3, 0x9b, 0x68,
+       0x97, 0x9b, 0xdf, 0x1f, 0xbf, 0x3f, 0xbf, 0xf7, 0x7b, 0x33, 0x03, 0xde, 0x30, 0x3e, 0x9f, 0x4a,
+       0xa1, 0x05, 0x69, 0x0c, 0xe3, 0xe0, 0x5b, 0x70, 0x5e, 0x50, 0x35, 0x22, 0xfb, 0xd0, 0x98, 0x5d,
+       0xf8, 0xd6, 0x89, 0xf5, 0xa4, 0x15, 0x36, 0x66, 0x17, 0x28, 0x3f, 0xf3, 0x1b, 0x46, 0x7e, 0x86,
+       0x72, 0xdf, 0xb7, 0x8d, 0xdc, 0x47, 0xf9, 0xd2, 0x77, 0x8c, 0x7c, 0x19, 0x7c, 0x09, 0xee, 0x8f,
+       0x52, 0xdc, 0x49, 0x3a, 0x21, 0x1f, 0x02, 0xcc, 0x26, 0xd1, 0x8c, 0x49, 0xc5, 0x45, 0x8a, 0x21,
+       0x9d, 0xb0, 0x3d, 0x9b, 0xbc, 0x2c, 0x14, 0x84, 0x80, 0x13, 0x8b, 0x84, 0x61, 0xec, 0xbd, 0x10,
+       0xbf, 0x83, 0x01, 0xb8, 0x57, 0x4a, 0x31, 0x3d, 0xb8, 0x7e, 0xe7, 0x42, 0x6e, 0xa0, 0x83, 0xa1,
+       0xae, 0x26, 0x22, 0x4b, 0x35, 0xf9, 0x04, 0x3c, 0x9a, 0x8b, 0x11, 0x4f, 0x30, 0x68, 0xa7, 0xdf,
+       0x39, 0x1f, 0xc6, 0xe7, 0x26, 0x5b, 0xe8, 0xa2, 0x71, 0x90, 0x90, 0x47, 0xd0, 0xa2, 0xf8, 0x07,
+       0xa6, 0x72, 0x42, 0x23, 0x05, 0x7f, 0x58, 0xd0, 0x45, 0xe7, 0x6b, 0xf6, 0x8a, 0xa7, 0x5c, 0xe7,
+       0x1d, 0xf4, 0xa1, 0x87, 0x9f, 0x74, 0x1c, 0x0d, 0xc7, 0x22, 0xfe, 0x79, 0x1e, 0xdb, 0xcb, 0x63,
+       0xe7, 0x78, 0x86, 0xfb, 0xc6, 0xe3, 0xab, 0xdc, 0x61, 0x90, 0x90, 0xcf, 0xa1, 0xc7, 0x95, 0xca,
+       0x68, 0x1a, 0xb3, 0x68, 0x5a, 0x00, 0x85, 0x99, 0x4c, 0x3d, 0x06, 0xbb, 0xb0, 0x5b, 0x3a, 0x95,
+       0x60, 0x1e, 0x83, 0x93, 0x50, 0x4d, 0xb1, 0xe1, 0xc5, 0xf8, 0xa8, 0x0d, 0xc6, 0xd0, 0x79, 0x49,
+       0xc7, 0x19, 0xbb, 0x15, 0x99, 0x8c, 0x19, 0x79, 0x0c, 0xb6, 0x64, 0xaf, 0xd6, 0x6a, 0xc9, 0x95,
+       0xe4, 0x14, 0x9a, 0xb3, 0xdc, 0xd5, 0x64, 0xed, 0x56, 0x28, 0x14, 0x40, 0x85, 0x85, 0x95, 0x3c,
+       0x06, 0x6f, 0x2a, 0x14, 0xf6, 0x89, 0x39, 0x9d, 0xb0, 0x92, 0x83, 0x5f, 0xa0, 0x87, 0xd9, 0xae,
+       0x99, 0xd2, 0x3c, 0xa5, 0x88, 0xc5, 0xff, 0x9c, 0xf2, 0x9f, 0x06, 0x74, 0x10, 0xc2, 0x17, 0x8c,
+       0x26, 0x4c, 0x12, 0x1f, 0xdc, 0x65, 0x62, 0x95, 0x22, 0x39, 0x83, 0xae, 0x62, 0x92, 0xd3, 0x31,
+       0x7f, 0x60, 0x49, 0xa4, 0xf8, 0x03, 0x33, 0x93, 0xdc, 0x9f, 0xab, 0x6f, 0xf9, 0x03, 0xcb, 0x27,
+       0x3d, 0x62, 0xfc, 0x6e, 0xa4, 0x4d, 0x32, 0x23, 0x91, 0xe7, 0x70, 0x30, 0x95, 0x6c, 0xc6, 0x45,
+       0xa6, 0xe6, 0x63, 0x75, 0x56, 0xfa, 0xea, 0x96, 0x2e, 0xe5, 0x5c, 0x8f, 0xc1, 0x51, 0x8c, 0x25,
+       0x7e, 0x73, 0x75, 0x3e, 0xb9, 0x96, 0x7c, 0x04, 0x7b, 0x9a, 0x4f, 0x98, 0xd2, 0x74, 0x32, 0x8d,
+       0x26, 0xca, 0x6f, 0x61, 0xc6, 0x4e, 0xa5, 0xbb, 0x51, 0xe4, 0x33, 0x38, 0xd0, 0x92, 0xa6, 0x8a,
+       0xc6, 0x79, 0xc3, 0x2a, 0x92, 0x42, 0x68, 0xdf, 0x5d, 0x89, 0xd6, 0x5b, 0x74, 0x09, 0x85, 0xd0,
+       0xe4, 0x29, 0x74, 0x90, 0xba, 0xe6, 0x07, 0x6f, 0xe5, 0x07, 0x28, 0x8c, 0xe8, 0x7a, 0x04, 0xcd,
+       0x54, 0xa4, 0x31, 0xf3, 0xdb, 0x98, 0xbd, 0x10, 0xf2, 0x35, 0x1c, 0x72, 0xad, 0x7c, 0x40, 0x25,
+       0x7e, 0x07, 0x7f, 0x59, 0xe0, 0xfd, 0x74, 0xff, 0xfe, 0xa0, 0x3e, 0x03, 0x90, 0x4c, 0x65, 0xe3,
+       0x7c, 0xfb, 0x94, 0x6f, 0x9f, 0xd8, 0x4b, 0x35, 0xb6, 0x0b, 0xdb, 0x20, 0x51, 0x15, 0xcb, 0x9d,
+       0x3a, 0x96, 0x93, 0x8f, 0xc1, 0x63, 0xf7, 0x3a, 0x1a, 0x51, 0x35, 0x5a, 0xc3, 0xd9, 0x65, 0xf7,
+       0x3a, 0xff, 0x08, 0xfe, 0xb5, 0xc0, 0xbe, 0xc9, 0xee, 0xc9, 0x53, 0x70, 0x15, 0x6e, 0x83, 0xf2,
+       0x2d, 0x4c, 0x88, 0xb4, 0x5b, 0xd8, 0x92, 0xb0, 0xb4, 0x93, 0x53, 0x70, 0xdf, 0xb0, 0x8a, 0xa5,
+       0x6d, 0x29, 0xbd, 0xbd, 0x21, 0x3d, 0xf9, 0x0e, 0x8e, 0x7e, 0xe5, 0x3a, 0x65, 0x4a, 0x45, 0xc9,
+       0x7c, 0x3d, 0x94, 0xef, 0x60, 0x0d, 0x47, 0x55, 0x0d, 0x0b, 0xbb, 0x13, 0x1e, 0x9a, 0x3f, 0x16,
+       0x74, 0x8a, 0x7c, 0x0a, 0x07, 0x65, 0x20, 0x2a, 0xef, 0xb2, 0x09, 0x4b, 0xb5, 0xf2, 0x9b, 0x27,
+       0xf6, 0x93, 0xbd, 0xb0, 0x67, 0x0c, 0x57, 0xa5, 0x3e, 0xf8, 0xdb, 0x82, 0xe6, 0xf7, 0x38, 0xce,
+       0x85, 0x5e, 0xac, 0x2d, 0x7b, 0x69, 0x6c, 0xea, 0xa5, 0xb6, 0x04, 0xbb, 0xbe, 0x04, 0xf2, 0x05,
+       0x1c, 0x56, 0xce, 0x69, 0x3c, 0x12, 0x92, 0x25, 0x75, 0x8b, 0x53, 0x46, 0xbc, 0x32, 0x3e, 0x83,
+       0x24, 0x10, 0xe0, 0x7d, 0x2d, 0x78, 0x3a, 0xa4, 0x8a, 0x91, 0x6f, 0xe6, 0x51, 0x16, 0xe0, 0x33,
+       0xad, 0xd4, 0xa3, 0x47, 0xd6, 0xd1, 0x23, 0xc7, 0xd0, 0xa6, 0x72, 0xc8, 0xb5, 0xa4, 0xf2, 0x37,
+       0x73, 0xc1, 0xcc, 0x15, 0xc1, 0x6b, 0x0b, 0x5a, 0x3f, 0x64, 0x7a, 0x9a, 0x69, 0x72, 0x06, 0xad,
+       0x82, 0x05, 0x26, 0xc5, 0x1a, 0x49, 0x8c, 0x99, 0x3c, 0x87, 0x6e, 0x2c, 0x52, 0x2d, 0xc5, 0xf8,
+       0x4d, 0xc7, 0xf6, 0xbe, 0xf1, 0xd9, 0xea, 0xd4, 0x5e, 0x1a, 0x82, 0xb3, 0x69, 0x08, 0x3e, 0xb8,
+       0x42, 0x26, 0x3c, 0xa5, 0x63, 0xe4, 0xbc, 0x13, 0x96, 0x62, 0xf0, 0xbb, 0x05, 0x10, 0x32, 0xcd,
+       0x25, 0xcb, 0x27, 0xb0, 0x7d, 0x2b, 0x65, 0x51, 0x8d, 0xb7, 0x16, 0x65, 0x6f, 0x51, 0x94, 0xb3,
+       0x5c, 0xd4, 0x9f, 0x36, 0x78, 0x03, 0x73, 0x77, 0x91, 0x53, 0x68, 0x17, 0x5c, 0xa8, 0xbb, 0x19,
+       0xbd, 0xc2, 0x34, 0x48, 0xb6, 0xbd, 0x1f, 0xde, 0x03, 0x98, 0x1b, 0xe8, 0xd5, 0xdc, 0x91, 0x5e,
+       0x37, 0xe0, 0x57, 0x5c, 0xc7, 0x47, 0x45, 0x52, 0x3d, 0x0a, 0xf0, 0x68, 0xef, 0xf4, 0x0f, 0xab,
+       0x1e, 0xe6, 0xef, 0x85, 0xf0, 0x51, 0xc9, 0xfd, 0x95, 0x77, 0x44, 0xed, 0x9e, 0xb9, 0xbb, 0xed,
+       0x99, 0xf7, 0xd6, 0x3d, 0x5b, 0x1c, 0x5a, 0x7b, 0x79, 0x68, 0xaf, 0x1b, 0xd0, 0xbc, 0x9d, 0xb2,
+       0x34, 0x21, 0x17, 0xd0, 0x55, 0x53, 0x96, 0xea, 0x48, 0xe0, 0x7e, 0xd4, 0xcd, 0xed, 0x03, 0x74,
+       0x28, 0xf6, 0xa7, 0xb8, 0xf8, 0xde, 0x95, 0x4d, 0x1b, 0xa6, 0xe2, 0xec, 0x38, 0x95, 0x5d, 0x4e,
+       0xcc, 0x4d, 0x30, 0xb6, 0x76, 0x82, 0xd1, 0x5d, 0x82, 0x71, 0xd8, 0xc2, 0xe7, 0xf4, 0xe5, 0x7f,
+       0x01, 0x00, 0x00, 0xff, 0xff, 0x0c, 0xb4, 0xe8, 0xef, 0x5a, 0x0b, 0x00, 0x00,
 }
index 9261066..d67b6a6 100644 (file)
@@ -87,6 +87,7 @@ message Nonce {
 
 message Coinbase {
   ValueDestination witness_destination = 1;
+  bytes            arbitrary           = 2;
 }
 
 message Output {
@@ -124,4 +125,4 @@ message Spend {
   repeated bytes   witness_arguments   = 5;
   Hash             witness_anchored_id = 6;
   uint64           ordinal             = 7;
-}
+}
\ No newline at end of file
index dd0cc37..1125146 100644 (file)
@@ -4,9 +4,10 @@ import "io"
 
 func (Coinbase) typ() string { return "coinbase1" }
 func (c *Coinbase) writeForHash(w io.Writer) {
-       //mustWriteForHash(w, c.WitnessDestination)
+       mustWriteForHash(w, c.Arbitrary)
 }
 
+// SetDestination is support function for map tx
 func (c *Coinbase) SetDestination(id *Hash, val *AssetAmount, pos uint64) {
        c.WitnessDestination = &ValueDestination{
                Ref:      id,
@@ -16,6 +17,6 @@ func (c *Coinbase) SetDestination(id *Hash, val *AssetAmount, pos uint64) {
 }
 
 // NewCoinbase creates a new Coinbase.
-func NewCoinbase() *Coinbase {
-       return &Coinbase{}
+func NewCoinbase(arbitrary []byte) *Coinbase {
+       return &Coinbase{Arbitrary: arbitrary}
 }
diff --git a/protocol/bc/legacy/coinbase.go b/protocol/bc/legacy/coinbase.go
new file mode 100644 (file)
index 0000000..a506237
--- /dev/null
@@ -0,0 +1,23 @@
+package legacy
+
+// CoinbaseInput is record the coinbase message
+type CoinbaseInput struct {
+       Arbitrary []byte
+}
+
+// IsIssuance is the interface function for return the struct type
+func (cb *CoinbaseInput) IsIssuance() bool { return false }
+
+// IsCoinbase is the interface function for return the struct type
+func (cb *CoinbaseInput) IsCoinbase() bool { return true }
+
+// NewCoinbaseInput create a new coinbase input struct
+func NewCoinbaseInput(arbitrary, referenceData []byte) *TxInput {
+       return &TxInput{
+               AssetVersion:  1,
+               ReferenceData: referenceData,
+               TypedInput: &CoinbaseInput{
+                       Arbitrary: arbitrary,
+               },
+       }
+}
index 4ae7268..307e29e 100644 (file)
@@ -20,6 +20,7 @@ type IssuanceInput struct {
 }
 
 func (ii *IssuanceInput) IsIssuance() bool { return true }
+func (ii *IssuanceInput) IsCoinbase() bool { return false }
 
 func (ii *IssuanceInput) AssetID() bc.AssetID {
        defhash := ii.AssetDefinitionHash()
index 0114d5c..91625ad 100644 (file)
@@ -44,6 +44,7 @@ func MapTx(oldTx *TxData) *bc.Tx {
                        ord = e.Ordinal
                        // resume below after the switch
 
+               case *bc.Coinbase:
                default:
                        continue
                }
@@ -80,6 +81,7 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                firstSpendID bc.Hash
                spends       []*bc.Spend
                issuances    []*bc.Issuance
+               coinbase     *bc.Coinbase
                muxSources   = make([]*bc.ValueSource, len(tx.Inputs))
        )
 
@@ -161,15 +163,18 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                }
        }
 
-       if tx.IsCoinbase() {
-               cb := bc.NewCoinbase()
-               cbID := addEntry(cb)
-
-               out := tx.Outputs[0]
-               muxSources = []*bc.ValueSource{{
-                       Ref:   &cbID,
-                       Value: &out.AssetAmount,
-               }}
+       if len(tx.Inputs) == 1 {
+               if oldCB, ok := tx.Inputs[0].TypedInput.(*CoinbaseInput); ok {
+                       cb := bc.NewCoinbase(oldCB.Arbitrary)
+                       cbID := addEntry(cb)
+
+                       out := tx.Outputs[0]
+                       muxSources = []*bc.ValueSource{{
+                               Ref:   &cbID,
+                               Value: &out.AssetAmount,
+                       }}
+                       coinbase = cb
+               }
        }
 
        mux := bc.NewMux(muxSources, &bc.Program{VmVersion: 1, Code: []byte{byte(vm.OP_TRUE)}})
@@ -183,7 +188,7 @@ func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash
                iss.SetDestination(&muxID, iss.Value, iss.Ordinal)
        }
 
-       if tx.IsCoinbase() {
+       if coinbase != nil {
                muxSource := mux.Sources[0]
                cb := entryMap[*muxSource.Ref].(*bc.Coinbase)
                cb.SetDestination(&muxID, muxSource.Value, 0)
index 732d58c..a06ca71 100644 (file)
@@ -66,7 +66,9 @@ func TestMapCoinbaseTx(t *testing.T) {
        }
        oldTx := &TxData{
                Version: 1,
-               Inputs:  []*TxInput{},
+               Inputs: []*TxInput{
+                       NewCoinbaseInput(nil, nil),
+               },
                Outputs: []*TxOutput{
                        NewTxOutput(*BTMAssetID, 800000000000, []byte{1}, nil),
                },
index 59a64cb..063211b 100644 (file)
@@ -23,6 +23,7 @@ type SpendInput struct {
 }
 
 func (si *SpendInput) IsIssuance() bool { return false }
+func (si *SpendInput) IsCoinbase() bool { return false }
 
 func NewSpendInput(arguments [][]byte, sourceID bc.Hash, assetID bc.AssetID, amount uint64, sourcePos uint64, controlProgram []byte, outRefDataHash bc.Hash, referenceData []byte) *TxInput {
        const (
index 25ec6bf..f48d37b 100644 (file)
@@ -104,11 +104,6 @@ func (tx *TxData) HasIssuance() bool {
        return false
 }
 
-// IsCoinbase returns true if this transaction is coinbase transaction.
-func (tx *TxData) IsCoinbase() bool {
-       return len(tx.Inputs) == 0 && len(tx.Outputs) == 1
-}
-
 func (tx *TxData) UnmarshalText(p []byte) error {
        b := make([]byte, hex.DecodedLen(len(p)))
        if _, err := hex.Decode(b, p); err != nil {
index 9f0aa53..d7d3c47 100644 (file)
@@ -226,43 +226,6 @@ func TestHasIssuance(t *testing.T) {
        }
 }
 
-func TestIsCoinbase(t *testing.T) {
-       cases := []struct {
-               tx   *TxData
-               want bool
-       }{{
-               tx: &TxData{
-                       Inputs: []*TxInput{NewIssuanceInput(nil, 0, nil, bc.Hash{}, nil, nil, nil)},
-               },
-               want: false,
-       }, {
-               tx: &TxData{
-                       Inputs: []*TxInput{
-                               NewSpendInput(nil, bc.Hash{}, bc.AssetID{}, 0, 0, nil, bc.Hash{}, nil),
-                               NewIssuanceInput(nil, 0, nil, bc.Hash{}, nil, nil, nil),
-                       },
-                       Outputs: []*TxOutput{
-                               NewTxOutput(bc.AssetID{}, 0, nil, nil),
-                       },
-               },
-               want: false,
-       }, {
-               tx: &TxData{
-                       Outputs: []*TxOutput{
-                               NewTxOutput(bc.AssetID{}, 0, nil, nil),
-                       },
-               },
-               want: true,
-       }}
-
-       for _, c := range cases {
-               got := c.tx.IsCoinbase()
-               if got != c.want {
-                       t.Errorf("IsCoinbase(%+v) = %v want %v", c.tx, got, c.want)
-               }
-       }
-}
-
 func TestInvalidIssuance(t *testing.T) {
        hex := ("07" + // serflags
                "01" + // transaction version
index 9520d4a..7abd86a 100644 (file)
@@ -23,6 +23,7 @@ type (
 
        TypedInput interface {
                IsIssuance() bool
+               IsCoinbase() bool
        }
 )
 
@@ -96,6 +97,7 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
        }
 
        var (
+               ci      *CoinbaseInput
                ii      *IssuanceInput
                si      *SpendInput
                assetID bc.AssetID
@@ -132,6 +134,12 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
                                return err
                        }
 
+               case 2:
+                       ci = new(CoinbaseInput)
+                       if ci.Arbitrary, err = blockchain.ReadVarstr31(r); err != nil {
+                               return err
+                       }
+
                default:
                        return fmt.Errorf("unsupported input type %d", icType[0])
                }
@@ -140,18 +148,20 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
        if err != nil {
                return err
        }
-
        t.ReferenceData, err = blockchain.ReadVarstr31(r)
        if err != nil {
                return err
        }
-
        t.WitnessSuffix, err = blockchain.ReadExtensibleString(r, func(r *blockchain.Reader) error {
                // TODO(bobg): test that serialization flags include SerWitness, when we relax the serflags-must-be-0x7 rule
                if t.AssetVersion != 1 {
                        return nil
                }
 
+               if ci != nil {
+                       return nil
+               }
+
                if ii != nil {
                        // read IssuanceInput witness
                        if _, err = ii.InitialBlock.ReadFrom(r); err != nil {
@@ -191,7 +201,9 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
        if err != nil {
                return err
        }
-       if ii != nil {
+       if ci != nil {
+               t.TypedInput = ci
+       } else if ii != nil {
                t.TypedInput = ii
        } else if si != nil {
                t.TypedInput = si
@@ -255,6 +267,14 @@ func (t *TxInput) WriteInputCommitment(w io.Writer, serflags uint8) (err error)
                        _, err = prevouthash.WriteTo(w)
                }
                return err
+
+       case *CoinbaseInput:
+               if _, err = w.Write([]byte{2}); err != nil {
+                       return err
+               }
+               if _, err = blockchain.WriteVarstr31(w, inp.Arbitrary); err != nil {
+                       return errors.Wrap(err, "writing coinbase arbitrary")
+               }
        }
        return nil
 }
index 7912179..c00d198 100644 (file)
@@ -458,6 +458,9 @@ func TestValidateBlock(t *testing.T) {
 func TestCoinbase(t *testing.T) {
        CbTx := mockCoinbaseTx(5000000000)
        errCbTx := legacy.MapTx(&legacy.TxData{
+               Inputs: []*legacy.TxInput{
+                       legacy.NewCoinbaseInput(nil, nil),
+               },
                Outputs: []*legacy.TxOutput{
                        legacy.NewTxOutput(bc.AssetID{
                                V0: uint64(18446744073709551611),
@@ -668,6 +671,9 @@ func mockBlock() *bc.Block {
 
 func mockCoinbaseTx(amount uint64) *bc.Tx {
        return legacy.MapTx(&legacy.TxData{
+               Inputs: []*legacy.TxInput{
+                       legacy.NewCoinbaseInput(nil, nil),
+               },
                Outputs: []*legacy.TxOutput{
                        legacy.NewTxOutput(*consensus.BTMAssetID, amount, []byte{1}, nil),
                },