bip143_test.go raw

   1  package tx
   2  
   3  import (
   4  	"encoding/hex"
   5  	"testing"
   6  )
   7  
   8  // The published BIP143 native P2WPKH example, from bip-0143.mediawiki. The digest below is the
   9  // specification's own, so this pins the preimage rather than checking it against itself.
  10  const (
  11  	bip143Hash = "c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670"
  12  
  13  	// The second input's witness program is 1d0f172a…a1, which is what the scriptCode wraps.
  14  	bip143Program = "1d0f172a0ecb48aee1be1f2687d2963ae33f71a1"
  15  
  16  	// The first input's outpoint, and both inputs' outpoints in order.
  17  	bip143Prev1 = "fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f"
  18  	bip143Prev2 = "ef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a"
  19  )
  20  
  21  // TestThePublishedBIP143Vector: the digest this package computes is the specification's.
  22  func TestThePublishedBIP143Vector(t *testing.T) {
  23  	transaction := New()
  24  	transaction.Version = 1
  25  
  26  	for _, prev := range []struct {
  27  		txid     string
  28  		index    uint32
  29  		sequence uint32
  30  	}{
  31  		{bip143Prev1, 0, 0xffffffee},
  32  		{bip143Prev2, 1, 0xffffffff},
  33  	} {
  34  		hash, err := hex.DecodeString(prev.txid)
  35  
  36  		if err != nil {
  37  			t.Fatal(err)
  38  		}
  39  
  40  		var outpoint [32]byte
  41  		copy(outpoint[:], hash)
  42  
  43  		transaction.AddInput(Outpoint{Hash: outpoint, Index: prev.index}, prev.sequence)
  44  	}
  45  
  46  	for _, output := range []struct {
  47  		value  uint64
  48  		script string
  49  	}{
  50  		{112340000, "76a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac"},
  51  		{223450000, "76a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac"},
  52  	} {
  53  		script, err := hex.DecodeString(output.script)
  54  
  55  		if err != nil {
  56  			t.Fatal(err)
  57  		}
  58  
  59  		transaction.AddOutput(output.value, script)
  60  	}
  61  
  62  	transaction.LockTime = 17
  63  
  64  	programRaw, err := hex.DecodeString(bip143Program)
  65  
  66  	if err != nil {
  67  		t.Fatal(err)
  68  	}
  69  
  70  	var program [20]byte
  71  	copy(program[:], programRaw)
  72  
  73  	// The second input is the P2WPKH one, and it spends 6 BTC.
  74  	digest, err := transaction.SighashV0(1, P2WPKHScriptCode(program), 600000000, SighashAll)
  75  
  76  	if err != nil {
  77  		t.Fatal(err)
  78  	}
  79  
  80  	if got := hex.EncodeToString(digest[:]); got != bip143Hash {
  81  		t.Fatalf("the digest is %s, the specification says %s", got, bip143Hash)
  82  	}
  83  }
  84