txscript: Use ScriptBuilder more.

This commit is contained in:
David Hill 2018-12-04 02:11:20 -05:00 committed by Dave Collins
parent ab7c1e8a67
commit 617fca8a93
2 changed files with 118 additions and 46 deletions

View File

@ -944,70 +944,38 @@ func GenerateSStxAddrPush(addr dcrutil.Address, amount dcrutil.Amount, limits ui
return nil, scriptError(ErrUnsupportedAddress, str)
}
// Prefix
dataPushes := []byte{
0x6a, // OP_RETURN
0x1e, // OP_DATA_30
}
hash := addr.ScriptAddress()
amountBuffer := make([]byte, 8)
binary.LittleEndian.PutUint64(amountBuffer, uint64(amount))
// Concatenate the prefix, pubkeyhash, and amount.
adBytes := make([]byte, 20+8+2)
copy(adBytes[0:20], addr.ScriptAddress())
binary.LittleEndian.PutUint64(adBytes[20:28], uint64(amount))
binary.LittleEndian.PutUint16(adBytes[28:30], limits)
// Set the bit flag indicating pay to script hash.
if scriptType == ScriptHashTy {
amountBuffer[7] |= 1 << 7
adBytes[27] |= 1 << 7
}
limitsBuffer := make([]byte, 2)
binary.LittleEndian.PutUint16(limitsBuffer, limits)
// Concatenate the prefix, pubkeyhash, and amount.
addrOut := append(dataPushes, hash...)
addrOut = append(addrOut, amountBuffer...)
addrOut = append(addrOut, limitsBuffer...)
return addrOut, nil
return NewScriptBuilder().AddOp(OP_RETURN).AddData(adBytes).Script()
}
// GenerateSSGenBlockRef generates an OP_RETURN push for the block header hash and
// height which the block votes on.
func GenerateSSGenBlockRef(blockHash chainhash.Hash, height uint32) ([]byte, error) {
// Prefix
dataPushes := []byte{
0x6a, // OP_RETURN
0x24, // OP_DATA_36
}
// Serialize the block hash and height
blockHeightBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(blockHeightBytes, height)
brBytes := make([]byte, 32+4)
copy(brBytes[0:32], blockHash[:])
binary.LittleEndian.PutUint32(brBytes[32:36], height)
blockData := append(blockHash[:], blockHeightBytes...)
// Concatenate the prefix and block data
blockDataOut := append(dataPushes, blockData...)
return blockDataOut, nil
return NewScriptBuilder().AddOp(OP_RETURN).AddData(brBytes).Script()
}
// GenerateSSGenVotes generates an OP_RETURN push for the vote bits in an SSGen tx.
func GenerateSSGenVotes(votebits uint16) ([]byte, error) {
// Prefix
dataPushes := []byte{
0x6a, // OP_RETURN
0x02, // OP_DATA_2
}
// Serialize the votebits
voteBitsBytes := make([]byte, 2)
binary.LittleEndian.PutUint16(voteBitsBytes, votebits)
vbBytes := make([]byte, 2)
binary.LittleEndian.PutUint16(vbBytes, votebits)
// Concatenate the prefix and vote bits
voteBitsOut := append(dataPushes, voteBitsBytes...)
return voteBitsOut, nil
return NewScriptBuilder().AddOp(OP_RETURN).AddData(vbBytes).Script()
}
// GenerateProvablyPruneableOut creates a provably-prunable script containing

View File

@ -11,6 +11,7 @@ import (
"testing"
"github.com/decred/dcrd/chaincfg"
"github.com/decred/dcrd/chaincfg/chainhash"
"github.com/decred/dcrd/dcrec"
"github.com/decred/dcrd/dcrec/secp256k1"
"github.com/decred/dcrd/dcrutil"
@ -1115,3 +1116,106 @@ func TestGenerateProvablyPruneableOut(t *testing.T) {
}
}
}
// TestGenerateSStxAddrPush ensures an expected OP_RETURN push is generated.
func TestGenerateSStxAddrPush(t *testing.T) {
var tests = []struct {
addrStr string
amount dcrutil.Amount
limits uint16
expected []byte
}{
{
"Dcur2mcGjmENx4DhNqDctW5wJCVyT3Qeqkx",
1000,
10,
hexToBytes("6a1ef5916158e3e2c4551c1796708db8367207ed1" +
"3bbe8030000000000800a00"),
},
{
"TscB7V5RuR1oXpA364DFEsNDuAs8Rk6BHJE",
543543,
256,
hexToBytes("6a1e7a5c4cca76f2e0b36db4763daacbd6cbb6ee6" +
"e7b374b0800000000000001"),
},
}
for _, test := range tests {
addr, err := dcrutil.DecodeAddress(test.addrStr)
if err != nil {
t.Errorf("DecodeAddress failed: %v", err)
continue
}
s, err := GenerateSStxAddrPush(addr, test.amount, test.limits)
if err != nil {
t.Errorf("GenerateSStxAddrPush failed: %v", err)
continue
}
if !bytes.Equal(s, test.expected) {
t.Errorf("GenerateSStxAddrPush: unexpected script:\n "+
"got %x\nwant %x", s, test.expected)
}
}
}
// TestGenerateSSGenBlockRef ensures an expected OP_RETURN push is generated.
func TestGenerateSSGenBlockRef(t *testing.T) {
var tests = []struct {
blockHash string
height uint32
expected []byte
}{
{
"0000000000004740ad140c86753f9295e09f9cc81b1bb75d7f5552aeeedb7012",
1000,
hexToBytes("6a241270dbeeae52557f5db71b1bc89c9fe095923" +
"f75860c14ad4047000000000000e8030000"),
},
{
"000000000000000033eafc268a67c8d1f02343d7a96cf3fe2a4915ef779b52f9",
290000,
hexToBytes("6a24f9529b77ef15492afef36ca9d74323f0d1c86" +
"78a26fcea330000000000000000d06c0400"),
},
}
for _, test := range tests {
h, err := chainhash.NewHashFromStr(test.blockHash)
if err != nil {
t.Errorf("NewHashFromStr failed: %v", err)
continue
}
s, err := GenerateSSGenBlockRef(*h, test.height)
if err != nil {
t.Errorf("GenerateSSGenBlockRef failed: %v", err)
continue
}
if !bytes.Equal(s, test.expected) {
t.Errorf("GenerateSSGenBlockRef: unexpected script:\n"+
" got %x\nwant %x", s, test.expected)
}
}
}
// TestGenerateSSGenVotes ensures an expected OP_RETURN push is generated.
func TestGenerateSSGenVotes(t *testing.T) {
var tests = []struct {
votebits uint16
expected []byte
}{
{65535, hexToBytes("6a02ffff")},
{256, hexToBytes("6a020001")},
{127, hexToBytes("6a027f00")},
{0, hexToBytes("6a020000")},
}
for _, test := range tests {
s, err := GenerateSSGenVotes(test.votebits)
if err != nil {
t.Errorf("GenerateSSGenVotes failed: %v", err)
continue
}
if !bytes.Equal(s, test.expected) {
t.Errorf("GenerateSSGenVotes: unexpected script:\n "+
"got %x\nwant %x", s, test.expected)
}
}
}