mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-08 07:06:43 +00:00
Replace p2pkh with p2pk (#1650)
* Replace p2pkh with p2pk * Fix tests * Fix comments and variable names * Add README.md for genkeypair * Rename pubkey->publicKey * Rename p2pkh to p2pk * Use util.PublicKeySize where needed * Remove redundant pointer * Fix comment * Rename pubKey->publicKey
This commit is contained in:
parent
d01a213f3d
commit
6afc06ce58
9
cmd/genkeypair/README.md
Normal file
9
cmd/genkeypair/README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
genkeypair
|
||||||
|
========
|
||||||
|
|
||||||
|
A tool for generating private-key-address pairs.
|
||||||
|
|
||||||
|
Note: This tool prints unencrypted private keys and is not recommended for day
|
||||||
|
to day use, and is intended mainly for tests.
|
||||||
|
|
||||||
|
In order to manage your funds it's recommended to use [kaspawallet](../kaspawallet)
|
26
cmd/genkeypair/config.go
Normal file
26
cmd/genkeypair/config.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jessevdk/go-flags"
|
||||||
|
"github.com/kaspanet/kaspad/infrastructure/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
type configFlags struct {
|
||||||
|
config.NetworkFlags
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseConfig() (*configFlags, error) {
|
||||||
|
cfg := &configFlags{}
|
||||||
|
parser := flags.NewParser(cfg, flags.PrintErrors|flags.HelpFlag)
|
||||||
|
_, err := parser.Parse()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = cfg.ResolveNetwork(parser)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg, nil
|
||||||
|
}
|
27
cmd/genkeypair/main.go
Normal file
27
cmd/genkeypair/main.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
||||||
|
"github.com/kaspanet/kaspad/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cfg, err := parseConfig()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
privateKey, publicKey, err := libkaspawallet.CreateKeyPair()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
addr, err := util.NewAddressPublicKey(publicKey, cfg.NetParams().Prefix)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Private key: %x\n", privateKey)
|
||||||
|
fmt.Printf("Address: %s\n", addr)
|
||||||
|
}
|
@ -26,9 +26,9 @@ func CreateKeyPair() ([]byte, []byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func addressFromPublicKey(params *dagconfig.Params, publicKeySerialized []byte) (util.Address, error) {
|
func addressFromPublicKey(params *dagconfig.Params, publicKeySerialized []byte) (util.Address, error) {
|
||||||
addr, err := util.NewAddressPubKeyHashFromPublicKey(publicKeySerialized[:], params.Prefix)
|
addr, err := util.NewAddressPublicKey(publicKeySerialized[:], params.Prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Failed to generate p2pkh address")
|
return nil, errors.Wrap(err, "Failed to generate p2pk address")
|
||||||
}
|
}
|
||||||
|
|
||||||
return addr, nil
|
return addr, nil
|
||||||
|
@ -254,7 +254,7 @@ func extractTransaction(psTx *serialization.PartiallySignedTransaction) (*extern
|
|||||||
psTx.Tx.Inputs[i].SignatureScript = sigScript
|
psTx.Tx.Inputs[i].SignatureScript = sigScript
|
||||||
} else {
|
} else {
|
||||||
if len(input.PubKeySignaturePairs) > 1 {
|
if len(input.PubKeySignaturePairs) > 1 {
|
||||||
return nil, errors.Errorf("Cannot sign on P2PKH when len(input.PubKeySignaturePairs) > 1")
|
return nil, errors.Errorf("Cannot sign on P2PK when len(input.PubKeySignaturePairs) > 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.PubKeySignaturePairs[0].Signature == nil {
|
if input.PubKeySignaturePairs[0].Signature == nil {
|
||||||
@ -263,7 +263,6 @@ func extractTransaction(psTx *serialization.PartiallySignedTransaction) (*extern
|
|||||||
|
|
||||||
sigScript, err := txscript.NewScriptBuilder().
|
sigScript, err := txscript.NewScriptBuilder().
|
||||||
AddData(input.PubKeySignaturePairs[0].Signature).
|
AddData(input.PubKeySignaturePairs[0].Signature).
|
||||||
AddData(input.PubKeySignaturePairs[0].PubKey).
|
|
||||||
Script()
|
Script()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -156,7 +156,7 @@ func TestMultisig(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestP2PKH(t *testing.T) {
|
func TestP2PK(t *testing.T) {
|
||||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||||
params.BlockCoinbaseMaturity = 0
|
params.BlockCoinbaseMaturity = 0
|
||||||
tc, teardown, err := consensus.NewFactory().NewTestConsensus(params, false, "TestMultisig")
|
tc, teardown, err := consensus.NewFactory().NewTestConsensus(params, false, "TestMultisig")
|
||||||
@ -181,7 +181,7 @@ func TestP2PKH(t *testing.T) {
|
|||||||
t.Fatalf("Address: %+v", err)
|
t.Fatalf("Address: %+v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := address.(*util.AddressPubKeyHash); !ok {
|
if _, ok := address.(*util.AddressPublicKey); !ok {
|
||||||
t.Fatalf("The address is of unexpected type")
|
t.Fatalf("The address is of unexpected type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@ func TestValidateTransactionInContextAndPopulateMassAndFee(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to serialize public key: %v", err)
|
t.Fatalf("Failed to serialize public key: %v", err)
|
||||||
}
|
}
|
||||||
addr, err := util.NewAddressPubKeyHashFromPublicKey(publicKeySerialized[:], params.Prefix)
|
addr, err := util.NewAddressPublicKey(publicKeySerialized[:], params.Prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to generate p2pkh address: %v", err)
|
t.Fatalf("Failed to generate p2pk address: %v", err)
|
||||||
}
|
}
|
||||||
scriptPublicKey, err := txscript.PayToAddrScript(addr)
|
scriptPublicKey, err := txscript.PayToAddrScript(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -261,9 +261,9 @@ func TestSigningTwoInputs(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to serialize public key: %v", err)
|
t.Fatalf("Failed to serialize public key: %v", err)
|
||||||
}
|
}
|
||||||
addr, err := util.NewAddressPubKeyHashFromPublicKey(publicKeySerialized[:], params.Prefix)
|
addr, err := util.NewAddressPublicKey(publicKeySerialized[:], params.Prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to generate p2pkh address: %v", err)
|
t.Fatalf("Failed to generate p2pk address: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptPublicKey, err := txscript.PayToAddrScript(addr)
|
scriptPublicKey, err := txscript.PayToAddrScript(addr)
|
||||||
|
@ -108,86 +108,86 @@ func TestCalculateSignatureHash(t *testing.T) {
|
|||||||
|
|
||||||
// sigHashAll
|
// sigHashAll
|
||||||
{name: "native-all-0", tx: nativeTx, hashType: all, inputIndex: 0,
|
{name: "native-all-0", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||||
expectedSignatureHash: "c899a5ea7414f0bbfd77e50674f46da34ce8722b928d4362a4b4b727c69c6499"},
|
expectedSignatureHash: "3e4a8effa6903dea5f762754ec410d732114ec2907e5bcbae7b6dd8d3f309a10"},
|
||||||
{name: "native-all-0-modify-input-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
{name: "native-all-0-modify-input-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||||
modificationFunction: modifyInput(1), // should change the hash
|
modificationFunction: modifyInput(1), // should change the hash
|
||||||
expectedSignatureHash: "faf3b9db2e07b1c14b2df02002d3e40f1e430f177ac5cd3354c84dad8fbe72ce"},
|
expectedSignatureHash: "0bd2947383101f9708d94d5799626c69c1b8472d2de66523c90c4a674e99cc51"},
|
||||||
{name: "native-all-0-modify-output-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
{name: "native-all-0-modify-output-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||||
modificationFunction: modifyOutput(1), // should change the hash
|
modificationFunction: modifyOutput(1), // should change the hash
|
||||||
expectedSignatureHash: "3a557c5b873aab72dcb81649642e1d7a63b75dcdcc74e19d340964a9e0eac76c"},
|
expectedSignatureHash: "ae69aa1372e958f069bf52d2628ead7ee789f195340b615ff0bcb6f01a995810"},
|
||||||
{name: "native-all-0-modify-sequence-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
{name: "native-all-0-modify-sequence-1", tx: nativeTx, hashType: all, inputIndex: 0,
|
||||||
modificationFunction: modifySequence(1), // should change the hash
|
modificationFunction: modifySequence(1), // should change the hash
|
||||||
expectedSignatureHash: "2dd5fe8f9fa4bf551ea2f080a26e07b2462083e12d3b2ed01cb9369a61920665"},
|
expectedSignatureHash: "51295575e7efc1fe1c2e741ade49089e3d780d15d26e9a0b18b3d90e35caf795"},
|
||||||
{name: "native-all-anyonecanpay-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
{name: "native-all-anyonecanpay-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||||
expectedSignatureHash: "19fe2e0db681017f318fda705a39bbbad9c1085514cfbcff6fac01e1725f758b"},
|
expectedSignatureHash: "0a13d3cab42a6cf3a7ef96f7b28c9bb0d98c209a3032ff85a6bfa7dac520f2c2"},
|
||||||
{name: "native-all-anyonecanpay-0-modify-input-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
{name: "native-all-anyonecanpay-0-modify-input-0", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||||
modificationFunction: modifyInput(0), // should change the hash
|
modificationFunction: modifyInput(0), // should change the hash
|
||||||
expectedSignatureHash: "5b21d492560a1c794595f769b3ae3c151775b9cfc4029d17c53f1856e1005da4"},
|
expectedSignatureHash: "aeaa56f5bc99daea0be5ed4b047808ce0123a81ac89c6089b72fa7199f5cd1c6"},
|
||||||
{name: "native-all-anyonecanpay-0-modify-input-1", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
{name: "native-all-anyonecanpay-0-modify-input-1", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||||
modificationFunction: modifyInput(1), // shouldn't change the hash
|
modificationFunction: modifyInput(1), // shouldn't change the hash
|
||||||
expectedSignatureHash: "19fe2e0db681017f318fda705a39bbbad9c1085514cfbcff6fac01e1725f758b"},
|
expectedSignatureHash: "0a13d3cab42a6cf3a7ef96f7b28c9bb0d98c209a3032ff85a6bfa7dac520f2c2"},
|
||||||
{name: "native-all-anyonecanpay-0-modify-sequence", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
{name: "native-all-anyonecanpay-0-modify-sequence", tx: nativeTx, hashType: allAnyoneCanPay, inputIndex: 0,
|
||||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||||
expectedSignatureHash: "19fe2e0db681017f318fda705a39bbbad9c1085514cfbcff6fac01e1725f758b"},
|
expectedSignatureHash: "0a13d3cab42a6cf3a7ef96f7b28c9bb0d98c209a3032ff85a6bfa7dac520f2c2"},
|
||||||
|
|
||||||
// sigHashNone
|
// sigHashNone
|
||||||
{name: "native-none-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
{name: "native-none-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||||
expectedSignatureHash: "fafabaabf6349fee4e18626b4eff015472f2317576a8f4bf7b0eea1df6f3e32b"},
|
expectedSignatureHash: "da53f7c726b55357adb1b644265fe7b9b7897cadde91a942d6127195c2ce99dc"},
|
||||||
{name: "native-none-0-modify-output-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
{name: "native-none-0-modify-output-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||||
expectedSignatureHash: "fafabaabf6349fee4e18626b4eff015472f2317576a8f4bf7b0eea1df6f3e32b"},
|
expectedSignatureHash: "da53f7c726b55357adb1b644265fe7b9b7897cadde91a942d6127195c2ce99dc"},
|
||||||
{name: "native-none-0-modify-sequence-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
{name: "native-none-0-modify-sequence-0", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||||
modificationFunction: modifySequence(0), // should change the hash
|
modificationFunction: modifySequence(0), // should change the hash
|
||||||
expectedSignatureHash: "daee0700e0ed4ab9f50de24d83e0bfce62999474ec8ceeb537ea35980662b601"},
|
expectedSignatureHash: "72c07c152a3792fb863d2de219ab4e863fe6779dc970a5c3958e26b3a3b9f139"},
|
||||||
{name: "native-none-0-modify-sequence-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
{name: "native-none-0-modify-sequence-1", tx: nativeTx, hashType: none, inputIndex: 0,
|
||||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||||
expectedSignatureHash: "fafabaabf6349fee4e18626b4eff015472f2317576a8f4bf7b0eea1df6f3e32b"},
|
expectedSignatureHash: "da53f7c726b55357adb1b644265fe7b9b7897cadde91a942d6127195c2ce99dc"},
|
||||||
{name: "native-none-anyonecanpay-0", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
{name: "native-none-anyonecanpay-0", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||||
expectedSignatureHash: "4e5c2d895f9711dc89c19d49ba478e9c8f4be0d82c9bd6b60d0361eb9b5296bc"},
|
expectedSignatureHash: "18eb79df328a516708f792cadfc4bf2be21b6add35fb6637a20347d532b1dce1"},
|
||||||
{name: "native-none-anyonecanpay-0-modify-amount-spent", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
{name: "native-none-anyonecanpay-0-modify-amount-spent", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||||
modificationFunction: modifyAmountSpent(0), // should change the hash
|
modificationFunction: modifyAmountSpent(0), // should change the hash
|
||||||
expectedSignatureHash: "9ce2f75eafc85b8e19133942c3143d14b61f2e7cc479fbc6d2fca026e50897f1"},
|
expectedSignatureHash: "674a8e6effa0bbfdb3df3ca45a7b17ab695cc0f9b3e0519e5bff165de13604e2"},
|
||||||
{name: "native-none-anyonecanpay-0-modify-script-public-key", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
{name: "native-none-anyonecanpay-0-modify-script-public-key", tx: nativeTx, hashType: noneAnyoneCanPay, inputIndex: 0,
|
||||||
modificationFunction: modifyScriptPublicKey(0), // should change the hash
|
modificationFunction: modifyScriptPublicKey(0), // should change the hash
|
||||||
expectedSignatureHash: "c6c364190520fe6c0419c2f45e25bf084356333b03ac7aaec28251126398bda3"},
|
expectedSignatureHash: "7a879d339c9b948c5264f1c0b8463f551221b2dcd575623f178cbbfcf7e01987"},
|
||||||
|
|
||||||
// sigHashSingle
|
// sigHashSingle
|
||||||
{name: "native-single-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
{name: "native-single-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||||
expectedSignatureHash: "6ff01d5d7cd82e24bc9ca0edec8bd6931ffb5aa1d303f07ca05dc89757343a92"},
|
expectedSignatureHash: "99c0a4a381fed9dbd651450d6ca969a6e8cdd941e9d73be086a1ba6c90fb630f"},
|
||||||
{name: "native-single-0-modify-output-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
{name: "native-single-0-modify-output-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||||
modificationFunction: modifyOutput(0), // should change the hash
|
modificationFunction: modifyOutput(0), // should change the hash
|
||||||
expectedSignatureHash: "d62af956aea369365bacc7e7f1aac106836994f1648311e82dd38da822c8771e"},
|
expectedSignatureHash: "92189a32391ca50a454d1853efed55acb1c49993911a1201df9891c866c483ee"},
|
||||||
{name: "native-single-0-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
{name: "native-single-0-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||||
expectedSignatureHash: "6ff01d5d7cd82e24bc9ca0edec8bd6931ffb5aa1d303f07ca05dc89757343a92"},
|
expectedSignatureHash: "99c0a4a381fed9dbd651450d6ca969a6e8cdd941e9d73be086a1ba6c90fb630f"},
|
||||||
{name: "native-single-0-modify-sequence-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
{name: "native-single-0-modify-sequence-0", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||||
modificationFunction: modifySequence(0), // should change the hash
|
modificationFunction: modifySequence(0), // should change the hash
|
||||||
expectedSignatureHash: "46692229d45bf2ceacb18960faba29753e325c0ade26ecf94495b91daacb828d"},
|
expectedSignatureHash: "765e2289df98b3a5269f112d4b36d57fe32c74d42e04a3046c6a3c8dd78a4121"},
|
||||||
{name: "native-single-0-modify-sequence-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
{name: "native-single-0-modify-sequence-1", tx: nativeTx, hashType: single, inputIndex: 0,
|
||||||
modificationFunction: modifySequence(1), // shouldn't change the hash
|
modificationFunction: modifySequence(1), // shouldn't change the hash
|
||||||
expectedSignatureHash: "6ff01d5d7cd82e24bc9ca0edec8bd6931ffb5aa1d303f07ca05dc89757343a92"},
|
expectedSignatureHash: "99c0a4a381fed9dbd651450d6ca969a6e8cdd941e9d73be086a1ba6c90fb630f"},
|
||||||
{name: "native-single-2-no-corresponding-output", tx: nativeTx, hashType: single, inputIndex: 2,
|
{name: "native-single-2-no-corresponding-output", tx: nativeTx, hashType: single, inputIndex: 2,
|
||||||
expectedSignatureHash: "d3cc385082a7f272ec2c8aae7f3a96ab2f49a4a4e1ed44d61af34058a7721281"},
|
expectedSignatureHash: "43de18c04d7fde81f49a40228d8730b4ceb0c66c77841c22622f59554769dd13"},
|
||||||
{name: "native-single-2-no-corresponding-output-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 2,
|
{name: "native-single-2-no-corresponding-output-modify-output-1", tx: nativeTx, hashType: single, inputIndex: 2,
|
||||||
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
modificationFunction: modifyOutput(1), // shouldn't change the hash
|
||||||
expectedSignatureHash: "d3cc385082a7f272ec2c8aae7f3a96ab2f49a4a4e1ed44d61af34058a7721281"},
|
expectedSignatureHash: "43de18c04d7fde81f49a40228d8730b4ceb0c66c77841c22622f59554769dd13"},
|
||||||
{name: "native-single-anyonecanpay-0", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 0,
|
{name: "native-single-anyonecanpay-0", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 0,
|
||||||
expectedSignatureHash: "408fcfd8ceca135c0f54569ccf8ac727e1aa6b5a15f87ccca765f1d5808aa4ea"},
|
expectedSignatureHash: "2e270f86fd68f780a5aa8d250364ab6786d990040268e5d561d09dde365dfab7"},
|
||||||
{name: "native-single-anyonecanpay-2-no-corresponding-output", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 2,
|
{name: "native-single-anyonecanpay-2-no-corresponding-output", tx: nativeTx, hashType: singleAnyoneCanPay, inputIndex: 2,
|
||||||
expectedSignatureHash: "685fac0d0b9dd3c5556f266714c4f7f93475d49fa12befb18e8297bc062aeaba"},
|
expectedSignatureHash: "afc05dd6b4a530cc3a4d7d23126548bd1f31c793e9282cbbfa27ff5566219501"},
|
||||||
|
|
||||||
// subnetwork transaction
|
// subnetwork transaction
|
||||||
{name: "subnetwork-all-0", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
{name: "subnetwork-all-0", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||||
expectedSignatureHash: "0e8b1433b761a220a61c0dc1f0fda909d49cef120d98d9f87344fef52dac0d8b"},
|
expectedSignatureHash: "5a67423ee048e067b94e2d4fc2960f62eceff6aa8b6c5ad71e3b7b7e5ff6bad7"},
|
||||||
{name: "subnetwork-all-modify-payload", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
{name: "subnetwork-all-modify-payload", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||||
modificationFunction: modifyPayload, // should change the hash
|
modificationFunction: modifyPayload, // should change the hash
|
||||||
expectedSignatureHash: "087315acb9193eaa14929dbe3d0ace80238aebe13eab3bf8db6c0a0d7ddb782e"},
|
expectedSignatureHash: "0d3bc5914da8dc8df081945fea1255359f380ca9baa8b31dfb3657c1e3c6038a"},
|
||||||
{name: "subnetwork-all-modify-gas", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
{name: "subnetwork-all-modify-gas", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||||
modificationFunction: modifyGas, // should change the hash
|
modificationFunction: modifyGas, // should change the hash
|
||||||
expectedSignatureHash: "07a90408ef45864ae8354b07a74cf826a4621391425ba417470a6e680af4ce70"},
|
expectedSignatureHash: "70abe9f947d0a0f5d735f9a063db8af41fe5902940f2693a1782119063097094"},
|
||||||
{name: "subnetwork-all-subnetwork-id", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
{name: "subnetwork-all-subnetwork-id", tx: subnetworkTx, hashType: all, inputIndex: 0,
|
||||||
modificationFunction: modifySubnetworkID, // should change the hash
|
modificationFunction: modifySubnetworkID, // should change the hash
|
||||||
expectedSignatureHash: "4ca44c2e35729ae5efe831a77027f1a58a41dbdd853459c26cbfe7d6c88783fb"},
|
expectedSignatureHash: "571a0b7ea905b7a6ff7ab825b72d23f911bac0bfaa7c4c97a4887a3d090925d4"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package hashes
|
package hashes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"hash"
|
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"hash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HashWriter is used to incrementally hash data without concatenating all of the data to a single buffer
|
// HashWriter is used to incrementally hash data without concatenating all of the data to a single buffer
|
||||||
|
@ -15,7 +15,7 @@ although it is still fairly powerful.
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
* [Standard Pay-to-pubkey-hash Script](http://godoc.org/github.com/kaspanet/kaspad/txscript#example-PayToAddrScript)
|
* [Standard Pay-to-pubkey Script](http://godoc.org/github.com/kaspanet/kaspad/txscript#example-PayToAddrScript)
|
||||||
Demonstrates creating a script which pays to a kaspa address. It also
|
Demonstrates creating a script which pays to a kaspa address. It also
|
||||||
prints the created script hex and uses the DisasmString function to display
|
prints the created script hex and uses the DisasmString function to display
|
||||||
the disassembled script.
|
the disassembled script.
|
||||||
|
@ -22,7 +22,7 @@ func ExamplePayToAddrScript() {
|
|||||||
// which is useful to ensure the accuracy of the address and determine
|
// which is useful to ensure the accuracy of the address and determine
|
||||||
// the address type. It is also required for the upcoming call to
|
// the address type. It is also required for the upcoming call to
|
||||||
// PayToAddrScript.
|
// PayToAddrScript.
|
||||||
addressStr := "kaspa:qqfgqp8l9l90zwetj84k2jcac2m8falvvyy8xjtnhdac2m8falvvyvc9fuvqt"
|
addressStr := "kaspa:qqj9fg59mptxkr9j0y53j5mwurcmda5mtza9n6v9pm9uj8h0wgk6uma5pvumr"
|
||||||
address, err := util.DecodeAddress(addressStr, util.Bech32PrefixKaspa)
|
address, err := util.DecodeAddress(addressStr, util.Bech32PrefixKaspa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
@ -45,15 +45,15 @@ func ExamplePayToAddrScript() {
|
|||||||
fmt.Println("Script Disassembly:", disasm)
|
fmt.Println("Script Disassembly:", disasm)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// Script Hex: 76aa20128004ff2fcaf13b2b91eb654b1dc2b674f7ec6108734973bb7b856ce9efd8c288ac
|
// Script Hex: 202454a285d8566b0cb2792919536ee0f1b6f69b58ba59e9850ecbc91eef722daeac
|
||||||
// Script Disassembly: OP_DUP OP_BLAKE2B 128004ff2fcaf13b2b91eb654b1dc2b674f7ec6108734973bb7b856ce9efd8c2 OP_EQUALVERIFY OP_CHECKSIG
|
// Script Disassembly: 2454a285d8566b0cb2792919536ee0f1b6f69b58ba59e9850ecbc91eef722dae OP_CHECKSIG
|
||||||
}
|
}
|
||||||
|
|
||||||
// This example demonstrates extracting information from a standard public key
|
// This example demonstrates extracting information from a standard public key
|
||||||
// script.
|
// script.
|
||||||
func ExampleExtractScriptPubKeyAddress() {
|
func ExampleExtractScriptPubKeyAddress() {
|
||||||
// Start with a standard pay-to-pubkey-hash script.
|
// Start with a standard pay-to-pubkey script.
|
||||||
scriptHex := "76aa20128004ff2fcaf13b2b91eb65128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac"
|
scriptHex := "2089ac24ea10bb751af4939623ccc5e550d96842b64e8fca0f63e94b4373fd555eac"
|
||||||
script, err := hex.DecodeString(scriptHex)
|
script, err := hex.DecodeString(scriptHex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
@ -74,6 +74,6 @@ func ExampleExtractScriptPubKeyAddress() {
|
|||||||
fmt.Println("Address:", address)
|
fmt.Println("Address:", address)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// Script Class: pubkeyhash
|
// Script Class: pubkey
|
||||||
// Address: kaspa:qqfgqp8l9l90zwetj84k2y5qqnljljh38v4er6m9fvwu9dn57lkxztu8quj75
|
// Address: kaspa:qzy6cf82zzah2xh5jwtz8nx9u4gdj6zzke8gljs0v055ksmnl424u6fv7ajrs
|
||||||
}
|
}
|
||||||
|
@ -48,16 +48,7 @@ func SignatureScript(tx *externalapi.DomainTransaction, idx int, hashType consen
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pk, err := privKey.SchnorrPublicKey()
|
return NewScriptBuilder().AddData(sig).Script()
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pkData, err := pk.Serialize()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewScriptBuilder().AddData(sig).AddData(pkData[:]).Script()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sign(dagParams *dagconfig.Params, tx *externalapi.DomainTransaction, idx int,
|
func sign(dagParams *dagconfig.Params, tx *externalapi.DomainTransaction, idx int,
|
||||||
@ -71,7 +62,7 @@ func sign(dagParams *dagconfig.Params, tx *externalapi.DomainTransaction, idx in
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch class {
|
switch class {
|
||||||
case PubKeyHashTy:
|
case PubKeyTy:
|
||||||
// look up key for address
|
// look up key for address
|
||||||
key, err := kdb.GetKey(address)
|
key, err := kdb.GetKey(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -143,7 +143,7 @@ func TestSignTxOutput(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// Pay to Pubkey Hash (merging with correct)
|
// Pay to Pubkey (merging with correct)
|
||||||
for _, hashType := range hashTypes {
|
for _, hashType := range hashTypes {
|
||||||
for _, input := range tx.Inputs {
|
for _, input := range tx.Inputs {
|
||||||
input.UTXOEntry = utxo.NewUTXOEntry(500, scriptPubKey, false, 100)
|
input.UTXOEntry = utxo.NewUTXOEntry(500, scriptPubKey, false, 100)
|
||||||
@ -180,14 +180,14 @@ func TestSignTxOutput(t *testing.T) {
|
|||||||
|
|
||||||
err = checkScripts(msg, tx, i, sigScript, scriptPubKey)
|
err = checkScripts(msg, tx, i, sigScript, scriptPubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("twice signed script invalid for "+
|
t.Fatalf("twice signed script invalid for "+
|
||||||
"%s: %v", msg, err)
|
"%s: %v", msg, err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pay to Pubkey Hash (compressed)
|
// Pay to Pubkey
|
||||||
for _, hashType := range hashTypes {
|
for _, hashType := range hashTypes {
|
||||||
for i := range tx.Inputs {
|
for i := range tx.Inputs {
|
||||||
msg := fmt.Sprintf("%d:%d", hashType, i)
|
msg := fmt.Sprintf("%d:%d", hashType, i)
|
||||||
@ -213,8 +213,7 @@ func TestSignTxOutput(t *testing.T) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
address, err := util.NewAddressPubKeyHash(
|
address, err := util.NewAddressPublicKey(serializedPubKey[:], util.Bech32PrefixKaspaTest)
|
||||||
util.HashBlake2b(serializedPubKey[:]), util.Bech32PrefixKaspaTest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to make address for %s: %v",
|
t.Errorf("failed to make address for %s: %v",
|
||||||
msg, err)
|
msg, err)
|
||||||
@ -238,7 +237,7 @@ func TestSignTxOutput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pay to Pubkey Hash with duplicate merge
|
// Pay to Pubkey with duplicate merge
|
||||||
for _, hashType := range hashTypes {
|
for _, hashType := range hashTypes {
|
||||||
for i := range tx.Inputs {
|
for i := range tx.Inputs {
|
||||||
msg := fmt.Sprintf("%d:%d", hashType, i)
|
msg := fmt.Sprintf("%d:%d", hashType, i)
|
||||||
@ -264,8 +263,7 @@ func TestSignTxOutput(t *testing.T) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
address, err := util.NewAddressPubKeyHash(
|
address, err := util.NewAddressPublicKey(serializedPubKey[:], util.Bech32PrefixKaspaTest)
|
||||||
util.HashBlake2b(serializedPubKey[:]), util.Bech32PrefixKaspaTest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to make address for %s: %v",
|
t.Errorf("failed to make address for %s: %v",
|
||||||
msg, err)
|
msg, err)
|
||||||
@ -316,7 +314,7 @@ func TestSignTxOutput(t *testing.T) {
|
|||||||
|
|
||||||
// As before, but with p2sh now.
|
// As before, but with p2sh now.
|
||||||
|
|
||||||
// Pay to Pubkey Hash
|
// Pay to Pubkey
|
||||||
for _, hashType := range hashTypes {
|
for _, hashType := range hashTypes {
|
||||||
for i := range tx.Inputs {
|
for i := range tx.Inputs {
|
||||||
msg := fmt.Sprintf("%d:%d", hashType, i)
|
msg := fmt.Sprintf("%d:%d", hashType, i)
|
||||||
@ -342,8 +340,7 @@ func TestSignTxOutput(t *testing.T) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
address, err := util.NewAddressPubKeyHash(
|
address, err := util.NewAddressPublicKey(serializedPubKey[:], util.Bech32PrefixKaspaTest)
|
||||||
util.HashBlake2b(serializedPubKey[:]), util.Bech32PrefixKaspaTest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to make address for %s: %v",
|
t.Errorf("failed to make address for %s: %v",
|
||||||
msg, err)
|
msg, err)
|
||||||
@ -381,7 +378,7 @@ func TestSignTxOutput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pay to Pubkey Hash (compressed) with duplicate merge
|
// Pay to Pubkey with duplicate merge
|
||||||
for _, hashType := range hashTypes {
|
for _, hashType := range hashTypes {
|
||||||
for i := range tx.Inputs {
|
for i := range tx.Inputs {
|
||||||
msg := fmt.Sprintf("%d:%d", hashType, i)
|
msg := fmt.Sprintf("%d:%d", hashType, i)
|
||||||
@ -407,8 +404,7 @@ func TestSignTxOutput(t *testing.T) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
address, err := util.NewAddressPubKeyHash(
|
address, err := util.NewAddressPublicKey(serializedPubKey[:], util.Bech32PrefixKaspaTest)
|
||||||
util.HashBlake2b(serializedPubKey[:]), util.Bech32PrefixKaspaTest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to make address for %s: %v",
|
t.Errorf("failed to make address for %s: %v",
|
||||||
msg, err)
|
msg, err)
|
||||||
@ -474,7 +470,7 @@ func TestSignTxOutput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateKeys() (keyPair *secp256k1.SchnorrKeyPair, scriptPublicKey *externalapi.ScriptPublicKey,
|
func generateKeys() (keyPair *secp256k1.SchnorrKeyPair, scriptPublicKey *externalapi.ScriptPublicKey,
|
||||||
addressPubKeyHash *util.AddressPubKeyHash, err error) {
|
addressPubKeyHash *util.AddressPublicKey, err error) {
|
||||||
|
|
||||||
key, err := secp256k1.GenerateSchnorrKeyPair()
|
key, err := secp256k1.GenerateSchnorrKeyPair()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -490,8 +486,7 @@ func generateKeys() (keyPair *secp256k1.SchnorrKeyPair, scriptPublicKey *externa
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, errors.Errorf("failed to serialize a pubkey for %s: %s", pubKey, err)
|
return nil, nil, nil, errors.Errorf("failed to serialize a pubkey for %s: %s", pubKey, err)
|
||||||
}
|
}
|
||||||
address, err := util.NewAddressPubKeyHash(
|
address, err := util.NewAddressPublicKey(serializedPubKey[:], util.Bech32PrefixKaspaTest)
|
||||||
util.HashBlake2b(serializedPubKey[:]), util.Bech32PrefixKaspaTest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, errors.Errorf("failed to make address for %s: %s", serializedPubKey, err)
|
return nil, nil, nil, errors.Errorf("failed to make address for %s: %s", serializedPubKey, err)
|
||||||
}
|
}
|
||||||
@ -534,12 +529,10 @@ var (
|
|||||||
oldCompressedScriptPubKey = &externalapi.ScriptPublicKey{[]byte{0x76, 0xa9, 0x14, 0x27, 0x4d, 0x9f, 0x7f,
|
oldCompressedScriptPubKey = &externalapi.ScriptPublicKey{[]byte{0x76, 0xa9, 0x14, 0x27, 0x4d, 0x9f, 0x7f,
|
||||||
0x61, 0x7e, 0x7c, 0x7a, 0x1c, 0x1f, 0xb2, 0x75, 0x79, 0x10,
|
0x61, 0x7e, 0x7c, 0x7a, 0x1c, 0x1f, 0xb2, 0x75, 0x79, 0x10,
|
||||||
0x43, 0x65, 0x68, 0x27, 0x9d, 0x86, 0x88, 0xac}, 0}
|
0x43, 0x65, 0x68, 0x27, 0x9d, 0x86, 0x88, 0xac}, 0}
|
||||||
p2pkhScriptPubKey = &externalapi.ScriptPublicKey{[]byte{0x76, 0xaa, 0x20,
|
p2pkScriptPubKey = &externalapi.ScriptPublicKey{[]byte{0x20, 0xb2, 0x52, 0xf0, 0x49, 0x85, 0x78, 0x03, 0x03,
|
||||||
0x51, 0x9c, 0x25, 0xca, 0x95, 0xa0, 0xd8, 0xcd,
|
0xc8, 0x7d, 0xce, 0x51, 0x7f, 0xa8, 0x69, 0x0b,
|
||||||
0xf5, 0xb8, 0x3f, 0x96, 0xa1, 0x5e, 0x8c, 0x1a,
|
0x91, 0x95, 0xf4, 0xf3, 0x5c, 0x26, 0x73, 0x05,
|
||||||
0xae, 0x33, 0xeb, 0x50, 0xc8, 0x66, 0xc9, 0xd0,
|
0x05, 0xa2, 0xee, 0xbc, 0x09, 0x38, 0x34, 0x3a, 0xac}, 0}
|
||||||
0xa5, 0xce, 0x3e, 0x5f, 0x6b, 0x3b, 0x38, 0x8d,
|
|
||||||
0x88, 0xac}, 0}
|
|
||||||
shortScriptPubKey = &externalapi.ScriptPublicKey{[]byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5,
|
shortScriptPubKey = &externalapi.ScriptPublicKey{[]byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5,
|
||||||
0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32,
|
0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32,
|
||||||
0x53, 0x90, 0x0e, 0x0a, 0x88, 0xac}, 0}
|
0x53, 0x90, 0x0e, 0x0a, 0x88, 0xac}, 0}
|
||||||
@ -638,7 +631,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal,
|
Value: coinbaseVal,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: true,
|
sigscriptGenerates: true,
|
||||||
inputValidates: true,
|
inputValidates: true,
|
||||||
@ -654,7 +647,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal,
|
Value: coinbaseVal,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: true,
|
sigscriptGenerates: true,
|
||||||
inputValidates: true,
|
inputValidates: true,
|
||||||
@ -663,7 +656,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal + fee,
|
Value: coinbaseVal + fee,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: true,
|
sigscriptGenerates: true,
|
||||||
inputValidates: true,
|
inputValidates: true,
|
||||||
@ -679,7 +672,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal,
|
Value: coinbaseVal,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: true,
|
sigscriptGenerates: true,
|
||||||
inputValidates: true,
|
inputValidates: true,
|
||||||
@ -695,7 +688,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal,
|
Value: coinbaseVal,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: true,
|
sigscriptGenerates: true,
|
||||||
inputValidates: true,
|
inputValidates: true,
|
||||||
@ -711,7 +704,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal,
|
Value: coinbaseVal,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: true,
|
sigscriptGenerates: true,
|
||||||
inputValidates: true,
|
inputValidates: true,
|
||||||
@ -727,7 +720,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal,
|
Value: coinbaseVal,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: false,
|
sigscriptGenerates: false,
|
||||||
inputValidates: false,
|
inputValidates: false,
|
||||||
@ -743,7 +736,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal,
|
Value: coinbaseVal,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: false,
|
sigscriptGenerates: false,
|
||||||
inputValidates: false,
|
inputValidates: false,
|
||||||
@ -759,7 +752,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal,
|
Value: coinbaseVal,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: true,
|
sigscriptGenerates: true,
|
||||||
inputValidates: true,
|
inputValidates: true,
|
||||||
@ -768,7 +761,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal + fee,
|
Value: coinbaseVal + fee,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: true,
|
sigscriptGenerates: true,
|
||||||
inputValidates: true,
|
inputValidates: true,
|
||||||
@ -784,7 +777,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal,
|
Value: coinbaseVal,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: true,
|
sigscriptGenerates: true,
|
||||||
inputValidates: true,
|
inputValidates: true,
|
||||||
@ -793,7 +786,7 @@ var sigScriptTests = []tstSigScript{
|
|||||||
{
|
{
|
||||||
txout: &externalapi.DomainTransactionOutput{
|
txout: &externalapi.DomainTransactionOutput{
|
||||||
Value: coinbaseVal + fee,
|
Value: coinbaseVal + fee,
|
||||||
ScriptPublicKey: p2pkhScriptPubKey,
|
ScriptPublicKey: p2pkScriptPubKey,
|
||||||
},
|
},
|
||||||
sigscriptGenerates: true,
|
sigscriptGenerates: true,
|
||||||
inputValidates: true,
|
inputValidates: true,
|
||||||
|
@ -21,7 +21,7 @@ type ScriptClass byte
|
|||||||
// Classes of script payment known about in the blockDAG.
|
// Classes of script payment known about in the blockDAG.
|
||||||
const (
|
const (
|
||||||
NonStandardTy ScriptClass = iota // None of the recognized forms.
|
NonStandardTy ScriptClass = iota // None of the recognized forms.
|
||||||
PubKeyHashTy // Pay pubkey hash.
|
PubKeyTy // Pay to pubkey.
|
||||||
ScriptHashTy // Pay to script hash.
|
ScriptHashTy // Pay to script hash.
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ const (
|
|||||||
// script class.
|
// script class.
|
||||||
var scriptClassToName = []string{
|
var scriptClassToName = []string{
|
||||||
NonStandardTy: "nonstandard",
|
NonStandardTy: "nonstandard",
|
||||||
PubKeyHashTy: "pubkeyhash",
|
PubKeyTy: "pubkey",
|
||||||
ScriptHashTy: "scripthash",
|
ScriptHashTy: "scripthash",
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,23 +43,20 @@ func (t ScriptClass) String() string {
|
|||||||
return scriptClassToName[t]
|
return scriptClassToName[t]
|
||||||
}
|
}
|
||||||
|
|
||||||
// isPubkeyHash returns true if the script passed is a pay-to-pubkey-hash
|
// isPayToPubkey returns true if the script passed is a pay-to-pubkey
|
||||||
// transaction, false otherwise.
|
// transaction, false otherwise.
|
||||||
func isPubkeyHash(pops []parsedOpcode) bool {
|
func isPayToPubkey(pops []parsedOpcode) bool {
|
||||||
return len(pops) == 5 &&
|
return len(pops) == 2 &&
|
||||||
pops[0].opcode.value == OpDup &&
|
pops[0].opcode.value == OpData32 &&
|
||||||
pops[1].opcode.value == OpBlake2b &&
|
pops[1].opcode.value == OpCheckSig
|
||||||
pops[2].opcode.value == OpData32 &&
|
|
||||||
pops[3].opcode.value == OpEqualVerify &&
|
|
||||||
pops[4].opcode.value == OpCheckSig
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// scriptType returns the type of the script being inspected from the known
|
// scriptType returns the type of the script being inspected from the known
|
||||||
// standard types.
|
// standard types.
|
||||||
func typeOfScript(pops []parsedOpcode) ScriptClass {
|
func typeOfScript(pops []parsedOpcode) ScriptClass {
|
||||||
if isPubkeyHash(pops) {
|
if isPayToPubkey(pops) {
|
||||||
return PubKeyHashTy
|
return PubKeyTy
|
||||||
} else if isScriptHash(pops) {
|
} else if isScriptHash(pops) {
|
||||||
return ScriptHashTy
|
return ScriptHashTy
|
||||||
}
|
}
|
||||||
@ -85,8 +82,8 @@ func GetScriptClass(script []byte) ScriptClass {
|
|||||||
func expectedInputs(pops []parsedOpcode, class ScriptClass) int {
|
func expectedInputs(pops []parsedOpcode, class ScriptClass) int {
|
||||||
switch class {
|
switch class {
|
||||||
|
|
||||||
case PubKeyHashTy:
|
case PubKeyTy:
|
||||||
return 2
|
return 1
|
||||||
|
|
||||||
case ScriptHashTy:
|
case ScriptHashTy:
|
||||||
// Not including script. That is handled by the caller.
|
// Not including script. That is handled by the caller.
|
||||||
@ -169,12 +166,13 @@ func CalcScriptInfo(sigScript, scriptPubKey []byte, isP2SH bool) (*ScriptInfo, e
|
|||||||
return si, nil
|
return si, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// payToPubKeyHashScript creates a new script to pay a transaction
|
// payToPubKeyScript creates a new script to pay a transaction
|
||||||
// output to a 20-byte pubkey hash. It is expected that the input is a valid
|
// output to a 32-byte pubkey. It is expected that the input is a valid
|
||||||
// hash.
|
// hash.
|
||||||
func payToPubKeyHashScript(pubKeyHash []byte) ([]byte, error) {
|
func payToPubKeyScript(pubKey []byte) ([]byte, error) {
|
||||||
return NewScriptBuilder().AddOp(OpDup).AddOp(OpBlake2b).
|
return NewScriptBuilder().
|
||||||
AddData(pubKeyHash).AddOp(OpEqualVerify).AddOp(OpCheckSig).
|
AddData(pubKey).
|
||||||
|
AddOp(OpCheckSig).
|
||||||
Script()
|
Script()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,12 +188,12 @@ func payToScriptHashScript(scriptHash []byte) ([]byte, error) {
|
|||||||
func PayToAddrScript(addr util.Address) (*externalapi.ScriptPublicKey, error) {
|
func PayToAddrScript(addr util.Address) (*externalapi.ScriptPublicKey, error) {
|
||||||
const nilAddrErrStr = "unable to generate payment script for nil address"
|
const nilAddrErrStr = "unable to generate payment script for nil address"
|
||||||
switch addr := addr.(type) {
|
switch addr := addr.(type) {
|
||||||
case *util.AddressPubKeyHash:
|
case *util.AddressPublicKey:
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
return nil, scriptError(ErrUnsupportedAddress,
|
return nil, scriptError(ErrUnsupportedAddress,
|
||||||
nilAddrErrStr)
|
nilAddrErrStr)
|
||||||
}
|
}
|
||||||
script, err := payToPubKeyHashScript(addr.ScriptAddress())
|
script, err := payToPubKeyScript(addr.ScriptAddress())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -276,12 +274,12 @@ func ExtractScriptPubKeyAddress(scriptPubKey *externalapi.ScriptPublicKey, dagPa
|
|||||||
|
|
||||||
scriptClass := typeOfScript(pops)
|
scriptClass := typeOfScript(pops)
|
||||||
switch scriptClass {
|
switch scriptClass {
|
||||||
case PubKeyHashTy:
|
case PubKeyTy:
|
||||||
// A pay-to-pubkey-hash script is of the form:
|
// A pay-to-pubkey script is of the form:
|
||||||
// OP_DUP OP_BLAKE2B <hash> OP_EQUALVERIFY OP_CHECKSIG
|
// <pubkey> OP_CHECKSIG
|
||||||
// Therefore the pubkey hash is the 3rd item on the stack.
|
// Therefore the pubkey is the first item on the stack.
|
||||||
// If the pubkey hash is invalid for some reason, return a nil address.
|
// If the pubkey is invalid for some reason, return a nil address.
|
||||||
addr, err := util.NewAddressPubKeyHash(pops[2].data,
|
addr, err := util.NewAddressPublicKey(pops[0].data,
|
||||||
dagParams.Prefix)
|
dagParams.Prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return scriptClass, nil, nil
|
return scriptClass, nil, nil
|
||||||
|
@ -28,14 +28,14 @@ func mustParseShortForm(script string, version uint16) []byte {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// newAddressPubKeyHash returns a new util.AddressPubKeyHash from the
|
// newAddressPublicKey returns a new util.AddressPublicKey from the
|
||||||
// provided hash. It panics if an error occurs. This is only used in the tests
|
// provided public key. It panics if an error occurs. This is only used in the tests
|
||||||
// as a helper since the only way it can fail is if there is an error in the
|
// as a helper since the only way it can fail is if there is an error in the
|
||||||
// test source code.
|
// test source code.
|
||||||
func newAddressPubKeyHash(pkHash []byte) util.Address {
|
func newAddressPublicKey(publicKey []byte) util.Address {
|
||||||
addr, err := util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixKaspa)
|
addr, err := util.NewAddressPublicKey(publicKey, util.Bech32PrefixKaspa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("invalid public key hash in test source")
|
panic("invalid public key in test source")
|
||||||
}
|
}
|
||||||
|
|
||||||
return addr
|
return addr
|
||||||
@ -67,15 +67,13 @@ func TestExtractScriptPubKeyAddrs(t *testing.T) {
|
|||||||
class ScriptClass
|
class ScriptClass
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "standard p2pkh",
|
name: "standard p2pk",
|
||||||
script: &externalapi.ScriptPublicKey{
|
script: &externalapi.ScriptPublicKey{
|
||||||
Script: hexToBytes("76aa20ad06dd6ddee55cbca9a9e3713bd" +
|
Script: hexToBytes("202454a285d8566b0cb2792919536ee0f1b6f69b58ba59e9850ecbc91eef722daeac"),
|
||||||
"7587509a30564ad06dd6ddee55cbca9a9e37188ac"),
|
|
||||||
Version: 0,
|
Version: 0,
|
||||||
},
|
},
|
||||||
addr: newAddressPubKeyHash(hexToBytes("ad06dd6ddee5" +
|
addr: newAddressPublicKey(hexToBytes("2454a285d8566b0cb2792919536ee0f1b6f69b58ba59e9850ecbc91eef722dae")),
|
||||||
"5cbca9a9e3713bd7587509a30564ad06dd6ddee55cbca9a9e371")),
|
class: PubKeyTy,
|
||||||
class: PubKeyHashTy,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "standard p2sh",
|
name: "standard p2sh",
|
||||||
@ -216,8 +214,8 @@ func TestCalcScriptInfo(t *testing.T) {
|
|||||||
{
|
{
|
||||||
// Invented scripts, the hashes do not match
|
// Invented scripts, the hashes do not match
|
||||||
name: "p2sh standard script",
|
name: "p2sh standard script",
|
||||||
sigScript: "1 81 DATA_37 DUP BLAKE2B DATA_32 0x010203" +
|
sigScript: "1 81 DATA_34 DATA_32 0x010203" +
|
||||||
"0405060708090a0b0c0d0e0f1011121314fe441065b6532231de2fac56 EQUALVERIFY " +
|
"0405060708090a0b0c0d0e0f1011121314fe441065b6532231de2fac56 " +
|
||||||
"CHECKSIG",
|
"CHECKSIG",
|
||||||
scriptPubKey: "BLAKE2B DATA_32 0xfe441065b6532231de2fac56" +
|
scriptPubKey: "BLAKE2B DATA_32 0xfe441065b6532231de2fac56" +
|
||||||
"3152205ec4f59c74fe441065b6532231de2fac56 EQUAL",
|
"3152205ec4f59c74fe441065b6532231de2fac56 EQUAL",
|
||||||
@ -225,7 +223,7 @@ func TestCalcScriptInfo(t *testing.T) {
|
|||||||
scriptInfo: ScriptInfo{
|
scriptInfo: ScriptInfo{
|
||||||
ScriptPubKeyClass: ScriptHashTy,
|
ScriptPubKeyClass: ScriptHashTy,
|
||||||
NumInputs: 3,
|
NumInputs: 3,
|
||||||
ExpectedInputs: 3, // nonstandard p2sh.
|
ExpectedInputs: 2, // nonstandard p2sh.
|
||||||
SigOps: 1,
|
SigOps: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -303,10 +301,10 @@ func (b *bogusAddress) Prefix() util.Bech32Prefix {
|
|||||||
func TestPayToAddrScript(t *testing.T) {
|
func TestPayToAddrScript(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
p2pkhMain, err := util.NewAddressPubKeyHash(hexToBytes("e34cce70c86"+
|
p2pkMain, err := util.NewAddressPublicKey(hexToBytes("e34cce70c86"+
|
||||||
"373273efcc54ce7d2a491bb4a0e84e34cce70c86373273efcc54c"), util.Bech32PrefixKaspa)
|
"373273efcc54ce7d2a491bb4a0e84e34cce70c86373273efcc54c"), util.Bech32PrefixKaspa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to create public key hash address: %v", err)
|
t.Fatalf("Unable to create public key address: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p2shMain, err := util.NewAddressScriptHashFromHash(hexToBytes("e8c300"+
|
p2shMain, err := util.NewAddressScriptHashFromHash(hexToBytes("e8c300"+
|
||||||
@ -325,11 +323,11 @@ func TestPayToAddrScript(t *testing.T) {
|
|||||||
expectedVersion uint16
|
expectedVersion uint16
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
// pay-to-pubkey-hash address on mainnet
|
// pay-to-pubkey address on mainnet
|
||||||
{
|
{
|
||||||
p2pkhMain,
|
p2pkMain,
|
||||||
"DUP BLAKE2B DATA_32 0xe34cce70c86373273efcc54ce7d2a4" +
|
"DATA_32 0xe34cce70c86373273efcc54ce7d2a4" +
|
||||||
"91bb4a0e84e34cce70c86373273efcc54c EQUALVERIFY CHECKSIG",
|
"91bb4a0e84e34cce70c86373273efcc54c CHECKSIG",
|
||||||
0,
|
0,
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
@ -343,7 +341,7 @@ func TestPayToAddrScript(t *testing.T) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Supported address types with nil pointers.
|
// Supported address types with nil pointers.
|
||||||
{(*util.AddressPubKeyHash)(nil), "", 0, errUnsupportedAddress},
|
{(*util.AddressPublicKey)(nil), "", 0, errUnsupportedAddress},
|
||||||
{(*util.AddressScriptHash)(nil), "", 0, errUnsupportedAddress},
|
{(*util.AddressScriptHash)(nil), "", 0, errUnsupportedAddress},
|
||||||
|
|
||||||
// Unsupported address type.
|
// Unsupported address type.
|
||||||
@ -393,16 +391,14 @@ var scriptClassTests = []struct {
|
|||||||
// p2pk
|
// p2pk
|
||||||
{
|
{
|
||||||
name: "Pay Pubkey",
|
name: "Pay Pubkey",
|
||||||
script: "DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
|
script: "DATA_32 0x89ac24ea10bb751af4939623ccc5e550d96842b64e8fca0f63e94b4373fd555e CHECKSIG",
|
||||||
"97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e16" +
|
class: PubKeyTy,
|
||||||
"0bfa9b8b64f9d4c03f999b8643f656b412a3 CHECKSIG",
|
|
||||||
class: NonStandardTy,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Pay PubkeyHash",
|
name: "Pay PubkeyHash",
|
||||||
script: "DUP BLAKE2B DATA_32 0x660d4ef3a743e3e696ad990364e55543e3e696ad990364e555e555" +
|
script: "DUP BLAKE2B DATA_32 0x660d4ef3a743e3e696ad990364e55543e3e696ad990364e555e555" +
|
||||||
"c271ad504b EQUALVERIFY CHECKSIG",
|
"c271ad504b EQUALVERIFY CHECKSIG",
|
||||||
class: PubKeyHashTy,
|
class: NonStandardTy,
|
||||||
},
|
},
|
||||||
// mutlisig
|
// mutlisig
|
||||||
{
|
{
|
||||||
@ -513,9 +509,9 @@ func TestStringifyClass(t *testing.T) {
|
|||||||
stringed: "nonstandard",
|
stringed: "nonstandard",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pubkeyhash",
|
name: "pubkey",
|
||||||
class: PubKeyHashTy,
|
class: PubKeyTy,
|
||||||
stringed: "pubkeyhash",
|
stringed: "pubkey",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "scripthash",
|
name: "scripthash",
|
||||||
|
@ -38,8 +38,8 @@ func main() {
|
|||||||
// later...
|
// later...
|
||||||
|
|
||||||
// Create and print new payment address, specific to the active network.
|
// Create and print new payment address, specific to the active network.
|
||||||
pubKeyHash := make([]byte, 20)
|
pubKey := make([]byte, 32)
|
||||||
addr, err := util.NewAddressPubKeyHash(pubKeyHash, dagParams)
|
addr, err := util.NewAddressPubKey(pubKey, dagParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,8 @@ variable (either directly, or hidden in a library call).
|
|||||||
// later...
|
// later...
|
||||||
|
|
||||||
// Create and print new payment address, specific to the active network.
|
// Create and print new payment address, specific to the active network.
|
||||||
pubKeyHash := make([]byte, 20)
|
pubKey := make([]byte, 32)
|
||||||
addr, err := util.NewAddressPubKeyHash(pubKeyHash, dagParams)
|
addr, err := util.NewAddressPubKey(pubKey, dagParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -127,43 +127,18 @@ func isDust(txOut *consensusexternalapi.DomainTransactionOutput, minRelayTxFee u
|
|||||||
// input script to redeem it. Since there is no input script
|
// input script to redeem it. Since there is no input script
|
||||||
// to redeem it yet, use the minimum size of a typical input script.
|
// to redeem it yet, use the minimum size of a typical input script.
|
||||||
//
|
//
|
||||||
// Pay-to-pubkey-hash bytes breakdown:
|
|
||||||
//
|
|
||||||
// Output to hash (34 bytes):
|
|
||||||
// 8 value, 1 script len, 25 script [1 OP_DUP, 1 OP_HASH_160,
|
|
||||||
// 1 OP_DATA_20, 20 hash, 1 OP_EQUALVERIFY, 1 OP_CHECKSIG]
|
|
||||||
//
|
|
||||||
// Input with compressed pubkey (148 bytes):
|
|
||||||
// 36 prev outpoint, 1 script len, 107 script [1 OP_DATA_72, 72 sig,
|
|
||||||
// 1 OP_DATA_33, 33 compressed pubkey], 4 sequence
|
|
||||||
//
|
|
||||||
// Input with uncompressed pubkey (180 bytes):
|
|
||||||
// 36 prev outpoint, 1 script len, 139 script [1 OP_DATA_72, 72 sig,
|
|
||||||
// 1 OP_DATA_65, 65 compressed pubkey], 4 sequence
|
|
||||||
//
|
|
||||||
// Pay-to-pubkey bytes breakdown:
|
// Pay-to-pubkey bytes breakdown:
|
||||||
//
|
//
|
||||||
// Output to compressed pubkey (44 bytes):
|
// Output to pubkey (43 bytes):
|
||||||
// 8 value, 1 script len, 35 script [1 OP_DATA_33,
|
// 8 value, 1 script len, 34 script [1 OP_DATA_32,
|
||||||
// 33 compressed pubkey, 1 OP_CHECKSIG]
|
// 32 pubkey, 1 OP_CHECKSIG]
|
||||||
//
|
//
|
||||||
// Output to uncompressed pubkey (76 bytes):
|
// Input (105 bytes):
|
||||||
// 8 value, 1 script len, 67 script [1 OP_DATA_65, 65 pubkey,
|
// 36 prev outpoint, 1 script len, 64 script [1 OP_DATA_64,
|
||||||
// 1 OP_CHECKSIG]
|
// 64 sig], 4 sequence
|
||||||
//
|
//
|
||||||
// Input (114 bytes):
|
// The most common scripts are pay-to-pubkey, and as per the above
|
||||||
// 36 prev outpoint, 1 script len, 73 script [1 OP_DATA_72,
|
// breakdown, the minimum size of a p2pk input script is 148 bytes. So
|
||||||
// 72 sig], 4 sequence
|
|
||||||
//
|
|
||||||
// Theoretically this could examine the script type of the output script
|
|
||||||
// and use a different size for the typical input script size for
|
|
||||||
// pay-to-pubkey vs pay-to-pubkey-hash inputs per the above breakdowns,
|
|
||||||
// but the only combination which is less than the value chosen is
|
|
||||||
// a pay-to-pubkey script with a compressed pubkey, which is not very
|
|
||||||
// common.
|
|
||||||
//
|
|
||||||
// The most common scripts are pay-to-pubkey-hash, and as per the above
|
|
||||||
// breakdown, the minimum size of a p2pkh input script is 148 bytes. So
|
|
||||||
// that figure is used.
|
// that figure is used.
|
||||||
totalSize := estimatedsize.TransactionOutputEstimatedSerializedSize(txOut) + 148
|
totalSize := estimatedsize.TransactionOutputEstimatedSerializedSize(txOut) + 148
|
||||||
|
|
||||||
@ -172,7 +147,7 @@ func isDust(txOut *consensusexternalapi.DomainTransactionOutput, minRelayTxFee u
|
|||||||
// minFreeTxRelayFee is in sompi/KB, so multiply by 1000 to
|
// minFreeTxRelayFee is in sompi/KB, so multiply by 1000 to
|
||||||
// convert to bytes.
|
// convert to bytes.
|
||||||
//
|
//
|
||||||
// Using the typical values for a pay-to-pubkey-hash transaction from
|
// Using the typical values for a pay-to-pubkey transaction from
|
||||||
// the breakdown above and the default minimum free transaction relay
|
// the breakdown above and the default minimum free transaction relay
|
||||||
// fee of 1000, this equates to values less than 546 sompi being
|
// fee of 1000, this equates to values less than 546 sompi being
|
||||||
// considered dust.
|
// considered dust.
|
||||||
|
@ -179,9 +179,9 @@ func TestCheckTransactionStandard(t *testing.T) {
|
|||||||
Sequence: constants.MaxTxInSequenceNum,
|
Sequence: constants.MaxTxInSequenceNum,
|
||||||
}
|
}
|
||||||
addrHash := [32]byte{0x01}
|
addrHash := [32]byte{0x01}
|
||||||
addr, err := util.NewAddressPubKeyHash(addrHash[:], util.Bech32PrefixKaspaTest)
|
addr, err := util.NewAddressPublicKey(addrHash[:], util.Bech32PrefixKaspaTest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("NewAddressPubKeyHash: unexpected error: %v", err)
|
t.Fatalf("NewAddressPublicKey: unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
dummyScriptPublicKey, err := txscript.PayToAddrScript(addr)
|
dummyScriptPublicKey, err := txscript.PayToAddrScript(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -200,7 +200,7 @@ func TestCheckTransactionStandard(t *testing.T) {
|
|||||||
code RejectCode
|
code RejectCode
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Typical pay-to-pubkey-hash transaction",
|
name: "Typical pay-to-pubkey transaction",
|
||||||
tx: consensusexternalapi.DomainTransaction{Version: 0, Inputs: []*consensusexternalapi.DomainTransactionInput{&dummyTxIn}, Outputs: []*consensusexternalapi.DomainTransactionOutput{&dummyTxOut}},
|
tx: consensusexternalapi.DomainTransaction{Version: 0, Inputs: []*consensusexternalapi.DomainTransactionInput{&dummyTxIn}, Outputs: []*consensusexternalapi.DomainTransactionOutput{&dummyTxOut}},
|
||||||
height: 300000,
|
height: 300000,
|
||||||
isStandard: true,
|
isStandard: true,
|
||||||
|
@ -15,7 +15,6 @@ import (
|
|||||||
"github.com/kaspanet/kaspad/util"
|
"github.com/kaspanet/kaspad/util"
|
||||||
"github.com/kaspanet/kaspad/util/panics"
|
"github.com/kaspanet/kaspad/util/panics"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/blake2b"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -178,8 +177,8 @@ func useDirOrCreateTemp(dataDir, tempName string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mineOnTips(client *rpc.Client) (appmessage.RejectReason, error) {
|
func mineOnTips(client *rpc.Client) (appmessage.RejectReason, error) {
|
||||||
fakePublicKeyHash := make([]byte, blake2b.Size256)
|
fakePublicKey := make([]byte, util.PublicKeySize)
|
||||||
addr, err := util.NewAddressPubKeyHash(fakePublicKeyHash, activeConfig().NetParams().Prefix)
|
addr, err := util.NewAddressPublicKey(fakePublicKey, activeConfig().NetParams().Prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return appmessage.RejectReasonNone, err
|
return appmessage.RejectReasonNone, err
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ func generateAddress() (util.Address, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return util.NewAddressPubKeyHashFromPublicKey(pubKeySerialized[:], activeConfig().ActiveNetParams.Prefix)
|
return util.NewAddressPublicKey(pubKeySerialized[:], activeConfig().ActiveNetParams.Prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
func areTipsAreEqual(resultA, resultB *appmessage.GetBlockDAGInfoResponseMessage) bool {
|
func areTipsAreEqual(resultA, resultB *appmessage.GetBlockDAGInfoResponseMessage) bool {
|
||||||
|
@ -18,14 +18,14 @@ const (
|
|||||||
rpcAddress2 = "127.0.0.1:12346"
|
rpcAddress2 = "127.0.0.1:12346"
|
||||||
rpcAddress3 = "127.0.0.1:12347"
|
rpcAddress3 = "127.0.0.1:12347"
|
||||||
|
|
||||||
miningAddress1 = "kaspasim:qr79e37hxdgkn4xjjmfxvqvayc5gsmsql2660d08u9ej9vnc8lzcywr265u64"
|
miningAddress1 = "kaspasim:qqqqnc0pxg7qw3qkc7l6sge8kfhsvvyt7mkw8uamtndqup27ftnd6c769gn66"
|
||||||
miningAddress1PrivateKey = "0ec5d7308f65717f3f0c3e4d962d73056c1c255a16593b3989589281b51ad5bc"
|
miningAddress1PrivateKey = "0d81045b0deb2af36a25403c2154c87aa82d89dd337b575bae27ce7f5de53cee"
|
||||||
|
|
||||||
miningAddress2 = "kaspasim:qpvr825ypd2fzq779yl83zvte2r4wlgxwra625rgthk9jj96d4cxgsegwryhg"
|
miningAddress2 = "kaspasim:qqqqnc0pxg7qw3qkc7l6sge8kfhsvvyt7mkw8uamtndqup27ftnd6c769gn66"
|
||||||
miningAddress2PrivateKey = "2a2e99d4a5c3e6d4add69e7baf66b9c7a2f17e74fad86cbd36a3a6815cecc10e"
|
miningAddress2PrivateKey = "0d81045b0deb2af36a25403c2154c87aa82d89dd337b575bae27ce7f5de53cee"
|
||||||
|
|
||||||
miningAddress3 = "kaspasim:qpvr825ypd2fzq779yl83zvte2r4wlgxwra625rgthk9jj96d4cxgsegwryhg"
|
miningAddress3 = "kaspasim:qqq754f2gdcjcnykwuwwr60c82rh5u6mxxe7yqxljnrxz9fu0h95kduq9ezng"
|
||||||
miningAddress3PrivateKey = "2a2e99d4a5c3e6d4add69e7baf66b9c7a2f17e74fad86cbd36a3a6815cecc10e"
|
miningAddress3PrivateKey = "f6c8f31fd359cbb97007034780bc4021f6ad01c6bc10499b79849efd4cc7ca39"
|
||||||
|
|
||||||
defaultTimeout = 10 * time.Second
|
defaultTimeout = 10 * time.Second
|
||||||
)
|
)
|
||||||
|
@ -20,8 +20,8 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// PubKeyHash addresses always have the version byte set to 0.
|
// PubKey addresses always have the version byte set to 0.
|
||||||
pubKeyHashAddrID = 0x00
|
pubKeyAddrID = 0x00
|
||||||
|
|
||||||
// ScriptHash addresses always have the version byte set to 8.
|
// ScriptHash addresses always have the version byte set to 8.
|
||||||
scriptHashAddrID = 0x08
|
scriptHashAddrID = 0x08
|
||||||
@ -79,16 +79,16 @@ func (prefix Bech32Prefix) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// encodeAddress returns a human-readable payment address given a network prefix
|
// encodeAddress returns a human-readable payment address given a network prefix
|
||||||
// and a blake2b hash which encodes the kaspa network and address type. It is used
|
// and a payload which encodes the kaspa network and address type. It is used
|
||||||
// in both pay-to-pubkey-hash (P2PKH) and pay-to-script-hash (P2SH) address
|
// in both pay-to-pubkey (P2PK) and pay-to-script-hash (P2SH) address
|
||||||
// encoding.
|
// encoding.
|
||||||
func encodeAddress(prefix Bech32Prefix, hash256 []byte, version byte) string {
|
func encodeAddress(prefix Bech32Prefix, payload []byte, version byte) string {
|
||||||
return bech32.Encode(prefix.String(), hash256[:blake2b.Size256], version)
|
return bech32.Encode(prefix.String(), payload, version)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address is an interface type for any type of destination a transaction
|
// Address is an interface type for any type of destination a transaction
|
||||||
// output may spend to. This includes pay-to-pubkey (P2PK), pay-to-pubkey-hash
|
// output may spend to. This includes pay-to-pubkey (P2PK)
|
||||||
// (P2PKH), and pay-to-script-hash (P2SH). Address is designed to be generic
|
// and pay-to-script-hash (P2SH). Address is designed to be generic
|
||||||
// enough that other kinds of addresses may be added in the future without
|
// enough that other kinds of addresses may be added in the future without
|
||||||
// changing the decoding and encoding API.
|
// changing the decoding and encoding API.
|
||||||
type Address interface {
|
type Address interface {
|
||||||
@ -98,7 +98,7 @@ type Address interface {
|
|||||||
// Please note that String differs subtly from EncodeAddress: String
|
// Please note that String differs subtly from EncodeAddress: String
|
||||||
// will return the value as a string without any conversion, while
|
// will return the value as a string without any conversion, while
|
||||||
// EncodeAddress may convert destination types (for example,
|
// EncodeAddress may convert destination types (for example,
|
||||||
// converting pubkeys to P2PKH addresses) before encoding as a
|
// converting pubkeys to P2PK addresses) before encoding as a
|
||||||
// payment address string.
|
// payment address string.
|
||||||
String() string
|
String() string
|
||||||
|
|
||||||
@ -139,95 +139,79 @@ func DecodeAddress(addr string, expectedPrefix Bech32Prefix) (Address, error) {
|
|||||||
prefix)
|
prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch on decoded length to determine the type.
|
|
||||||
switch len(decoded) {
|
|
||||||
case blake2b.Size256: // P2PKH or P2SH
|
|
||||||
switch version {
|
switch version {
|
||||||
case pubKeyHashAddrID:
|
case pubKeyAddrID:
|
||||||
return newAddressPubKeyHash(prefix, decoded)
|
return newAddressPubKey(prefix, decoded)
|
||||||
case scriptHashAddrID:
|
case scriptHashAddrID:
|
||||||
return newAddressScriptHashFromHash(prefix, decoded)
|
return newAddressScriptHashFromHash(prefix, decoded)
|
||||||
default:
|
default:
|
||||||
return nil, ErrUnknownAddressType
|
return nil, ErrUnknownAddressType
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
return nil, errors.New("decoded address is of unknown size")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressPubKeyHash is an Address for a pay-to-pubkey-hash (P2PKH)
|
// PublicKeySize is the public key size for a schnorr public key
|
||||||
|
const PublicKeySize = 32
|
||||||
|
|
||||||
|
// AddressPublicKey is an Address for a pay-to-pubkey (P2PK)
|
||||||
// transaction.
|
// transaction.
|
||||||
type AddressPubKeyHash struct {
|
type AddressPublicKey struct {
|
||||||
prefix Bech32Prefix
|
prefix Bech32Prefix
|
||||||
hash [blake2b.Size256]byte
|
publicKey [PublicKeySize]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAddressPubKeyHashFromPublicKey returns a new AddressPubKeyHash from given public key
|
// NewAddressPublicKey returns a new AddressPublicKey. publicKey must be 32
|
||||||
func NewAddressPubKeyHashFromPublicKey(publicKey []byte, prefix Bech32Prefix) (*AddressPubKeyHash, error) {
|
|
||||||
pkHash := HashBlake2b(publicKey)
|
|
||||||
return newAddressPubKeyHash(prefix, pkHash)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAddressPubKeyHash returns a new AddressPubKeyHash. pkHash mustbe 20
|
|
||||||
// bytes.
|
// bytes.
|
||||||
func NewAddressPubKeyHash(pkHash []byte, prefix Bech32Prefix) (*AddressPubKeyHash, error) {
|
func NewAddressPublicKey(publicKey []byte, prefix Bech32Prefix) (*AddressPublicKey, error) {
|
||||||
return newAddressPubKeyHash(prefix, pkHash)
|
return newAddressPubKey(prefix, publicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newAddressPubKeyHash is the internal API to create a pubkey hash address
|
// newAddressPubKey is the internal API to create a pubkey address
|
||||||
// with a known leading identifier byte for a network, rather than looking
|
// with a known leading identifier byte for a network, rather than looking
|
||||||
// it up through its parameters. This is useful when creating a new address
|
// it up through its parameters. This is useful when creating a new address
|
||||||
// structure from a string encoding where the identifier byte is already
|
// structure from a string encoding where the identifier byte is already
|
||||||
// known.
|
// known.
|
||||||
func newAddressPubKeyHash(prefix Bech32Prefix, pkHash []byte) (*AddressPubKeyHash, error) {
|
func newAddressPubKey(prefix Bech32Prefix, publicKey []byte) (*AddressPublicKey, error) {
|
||||||
// Check for a valid pubkey hash length.
|
// Check for a valid pubkey length.
|
||||||
if len(pkHash) != blake2b.Size256 {
|
if len(publicKey) != PublicKeySize {
|
||||||
return nil, errors.Errorf("pkHash must be %d bytes", blake2b.Size256)
|
return nil, errors.Errorf("publicKey must be %d bytes", PublicKeySize)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := &AddressPubKeyHash{prefix: prefix}
|
addr := &AddressPublicKey{prefix: prefix}
|
||||||
copy(addr.hash[:], pkHash)
|
copy(addr.publicKey[:], publicKey)
|
||||||
return addr, nil
|
return addr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeAddress returns the string encoding of a pay-to-pubkey-hash
|
// EncodeAddress returns the string encoding of a pay-to-pubkey
|
||||||
// address. Part of the Address interface.
|
// address. Part of the Address interface.
|
||||||
func (a *AddressPubKeyHash) EncodeAddress() string {
|
func (a *AddressPublicKey) EncodeAddress() string {
|
||||||
return encodeAddress(a.prefix, a.hash[:], pubKeyHashAddrID)
|
return encodeAddress(a.prefix, a.publicKey[:], pubKeyAddrID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScriptAddress returns the bytes to be included in a txout script to pay
|
// ScriptAddress returns the bytes to be included in a txout script to pay
|
||||||
// to a pubkey hash. Part of the Address interface.
|
// to a pubkey. Part of the Address interface.
|
||||||
func (a *AddressPubKeyHash) ScriptAddress() []byte {
|
func (a *AddressPublicKey) ScriptAddress() []byte {
|
||||||
return a.hash[:]
|
return a.publicKey[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsForPrefix returns whether or not the pay-to-pubkey-hash address is associated
|
// IsForPrefix returns whether or not the pay-to-pubkey address is associated
|
||||||
// with the passed kaspa network.
|
// with the passed kaspa network.
|
||||||
func (a *AddressPubKeyHash) IsForPrefix(prefix Bech32Prefix) bool {
|
func (a *AddressPublicKey) IsForPrefix(prefix Bech32Prefix) bool {
|
||||||
return a.prefix == prefix
|
return a.prefix == prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefix returns the prefix for this address
|
// Prefix returns the prefix for this address
|
||||||
func (a *AddressPubKeyHash) Prefix() Bech32Prefix {
|
func (a *AddressPublicKey) Prefix() Bech32Prefix {
|
||||||
return a.prefix
|
return a.prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a human-readable string for the pay-to-pubkey-hash address.
|
// String returns a human-readable string for the pay-to-pubkey address.
|
||||||
// This is equivalent to calling EncodeAddress, but is provided so the type can
|
// This is equivalent to calling EncodeAddress, but is provided so the type can
|
||||||
// be used as a fmt.Stringer.
|
// be used as a fmt.Stringer.
|
||||||
func (a *AddressPubKeyHash) String() string {
|
func (a *AddressPublicKey) String() string {
|
||||||
return a.EncodeAddress()
|
return a.EncodeAddress()
|
||||||
}
|
}
|
||||||
|
|
||||||
// HashBlake2b returns the underlying array of the pubkey hash. This can be useful
|
// AddressScriptHash is an Address for a pay-to-script-publicKey (P2SH)
|
||||||
// when an array is more appropiate than a slice (for example, when used as map
|
|
||||||
// keys).
|
|
||||||
func (a *AddressPubKeyHash) HashBlake2b() *[blake2b.Size256]byte {
|
|
||||||
return &a.hash
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddressScriptHash is an Address for a pay-to-script-hash (P2SH)
|
|
||||||
// transaction.
|
// transaction.
|
||||||
type AddressScriptHash struct {
|
type AddressScriptHash struct {
|
||||||
prefix Bech32Prefix
|
prefix Bech32Prefix
|
||||||
|
@ -26,99 +26,99 @@ func TestAddresses(t *testing.T) {
|
|||||||
passedPrefix util.Bech32Prefix
|
passedPrefix util.Bech32Prefix
|
||||||
expectedPrefix util.Bech32Prefix
|
expectedPrefix util.Bech32Prefix
|
||||||
}{
|
}{
|
||||||
// Positive P2PKH tests.
|
// Positive P2PK tests.
|
||||||
{
|
{
|
||||||
name: "mainnet p2pkh",
|
name: "mainnet p2pk",
|
||||||
addr: "kaspa:qr35ennsep3hxfe7lnz5ee7j5jgmkjswsn35ennsep3hxfe7ln35cdv0dy335",
|
addr: "kaspa:qr35ennsep3hxfe7lnz5ee7j5jgmkjswsn35ennsep3hxfe7ln35cdv0dy335",
|
||||||
encoded: "kaspa:qr35ennsep3hxfe7lnz5ee7j5jgmkjswsn35ennsep3hxfe7ln35cdv0dy335",
|
encoded: "kaspa:qr35ennsep3hxfe7lnz5ee7j5jgmkjswsn35ennsep3hxfe7ln35cdv0dy335",
|
||||||
valid: true,
|
valid: true,
|
||||||
result: util.TstAddressPubKeyHash(
|
result: util.TstAddressPubKey(
|
||||||
util.Bech32PrefixKaspa,
|
util.Bech32PrefixKaspa,
|
||||||
[blake2b.Size256]byte{
|
[util.PublicKeySize]byte{
|
||||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||||
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84,
|
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84,
|
||||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||||
0xe3, 0x4c,
|
0xe3, 0x4c,
|
||||||
}),
|
}),
|
||||||
f: func() (util.Address, error) {
|
f: func() (util.Address, error) {
|
||||||
pkHash := []byte{
|
publicKey := []byte{
|
||||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||||
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84,
|
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84,
|
||||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||||
0xe3, 0x4c}
|
0xe3, 0x4c}
|
||||||
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixKaspa)
|
return util.NewAddressPublicKey(publicKey, util.Bech32PrefixKaspa)
|
||||||
},
|
},
|
||||||
passedPrefix: util.Bech32PrefixUnknown,
|
passedPrefix: util.Bech32PrefixUnknown,
|
||||||
expectedPrefix: util.Bech32PrefixKaspa,
|
expectedPrefix: util.Bech32PrefixKaspa,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mainnet p2pkh 2",
|
name: "mainnet p2pk 2",
|
||||||
addr: "kaspa:qq80qvqs0lfxuzmt7sz3909ze6camq9d4t35ennsep3hxfe7ln35cvfqgz3z8",
|
addr: "kaspa:qq80qvqs0lfxuzmt7sz3909ze6camq9d4t35ennsep3hxfe7ln35cvfqgz3z8",
|
||||||
encoded: "kaspa:qq80qvqs0lfxuzmt7sz3909ze6camq9d4t35ennsep3hxfe7ln35cvfqgz3z8",
|
encoded: "kaspa:qq80qvqs0lfxuzmt7sz3909ze6camq9d4t35ennsep3hxfe7ln35cvfqgz3z8",
|
||||||
valid: true,
|
valid: true,
|
||||||
result: util.TstAddressPubKeyHash(
|
result: util.TstAddressPubKey(
|
||||||
util.Bech32PrefixKaspa,
|
util.Bech32PrefixKaspa,
|
||||||
[blake2b.Size256]byte{
|
[util.PublicKeySize]byte{
|
||||||
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
|
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
|
||||||
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa,
|
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa,
|
||||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||||
0xe3, 0x4c,
|
0xe3, 0x4c,
|
||||||
}),
|
}),
|
||||||
f: func() (util.Address, error) {
|
f: func() (util.Address, error) {
|
||||||
pkHash := []byte{
|
publicKey := []byte{
|
||||||
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
|
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
|
||||||
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa,
|
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa,
|
||||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||||
0xe3, 0x4c,
|
0xe3, 0x4c,
|
||||||
}
|
}
|
||||||
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixKaspa)
|
return util.NewAddressPublicKey(publicKey, util.Bech32PrefixKaspa)
|
||||||
},
|
},
|
||||||
passedPrefix: util.Bech32PrefixKaspa,
|
passedPrefix: util.Bech32PrefixKaspa,
|
||||||
expectedPrefix: util.Bech32PrefixKaspa,
|
expectedPrefix: util.Bech32PrefixKaspa,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "testnet p2pkh",
|
name: "testnet p2pk",
|
||||||
addr: "kaspatest:qputx94qseratdmjs0j395mq8u03er0x3l35ennsep3hxfe7ln35ckquw528z",
|
addr: "kaspatest:qputx94qseratdmjs0j395mq8u03er0x3l35ennsep3hxfe7ln35ckquw528z",
|
||||||
encoded: "kaspatest:qputx94qseratdmjs0j395mq8u03er0x3l35ennsep3hxfe7ln35ckquw528z",
|
encoded: "kaspatest:qputx94qseratdmjs0j395mq8u03er0x3l35ennsep3hxfe7ln35ckquw528z",
|
||||||
valid: true,
|
valid: true,
|
||||||
result: util.TstAddressPubKeyHash(
|
result: util.TstAddressPubKey(
|
||||||
util.Bech32PrefixKaspaTest,
|
util.Bech32PrefixKaspaTest,
|
||||||
[blake2b.Size256]byte{
|
[util.PublicKeySize]byte{
|
||||||
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
||||||
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f,
|
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f,
|
||||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||||
0xe3, 0x4c,
|
0xe3, 0x4c,
|
||||||
}),
|
}),
|
||||||
f: func() (util.Address, error) {
|
f: func() (util.Address, error) {
|
||||||
pkHash := []byte{
|
publicKey := []byte{
|
||||||
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
||||||
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f,
|
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f,
|
||||||
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
||||||
0xe3, 0x4c,
|
0xe3, 0x4c,
|
||||||
}
|
}
|
||||||
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixKaspaTest)
|
return util.NewAddressPublicKey(publicKey, util.Bech32PrefixKaspaTest)
|
||||||
},
|
},
|
||||||
passedPrefix: util.Bech32PrefixKaspaTest,
|
passedPrefix: util.Bech32PrefixKaspaTest,
|
||||||
expectedPrefix: util.Bech32PrefixKaspaTest,
|
expectedPrefix: util.Bech32PrefixKaspaTest,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Negative P2PKH tests.
|
// Negative P2PK tests.
|
||||||
{
|
{
|
||||||
name: "p2pkh wrong hash length",
|
name: "p2pk wrong public key length",
|
||||||
addr: "",
|
addr: "",
|
||||||
valid: false,
|
valid: false,
|
||||||
f: func() (util.Address, error) {
|
f: func() (util.Address, error) {
|
||||||
pkHash := []byte{
|
publicKey := []byte{
|
||||||
0x00, 0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b,
|
0x00, 0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b,
|
||||||
0xf4, 0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad,
|
0xf4, 0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad,
|
||||||
0xaa}
|
0xaa}
|
||||||
return util.NewAddressPubKeyHash(pkHash, util.Bech32PrefixKaspa)
|
return util.NewAddressPublicKey(publicKey, util.Bech32PrefixKaspa)
|
||||||
},
|
},
|
||||||
passedPrefix: util.Bech32PrefixKaspa,
|
passedPrefix: util.Bech32PrefixKaspa,
|
||||||
expectedPrefix: util.Bech32PrefixKaspa,
|
expectedPrefix: util.Bech32PrefixKaspa,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "p2pkh bad checksum",
|
name: "p2pk bad checksum",
|
||||||
addr: "kaspa:qr35ennsep3hxfe7lnz5ee7j5jgmkjswss74as46gx",
|
addr: "kaspa:qr35ennsep3hxfe7lnz5ee7j5jgmkjswss74as46gx",
|
||||||
valid: false,
|
valid: false,
|
||||||
passedPrefix: util.Bech32PrefixKaspa,
|
passedPrefix: util.Bech32PrefixKaspa,
|
||||||
@ -270,23 +270,22 @@ func TestAddresses(t *testing.T) {
|
|||||||
// Perform type-specific calculations.
|
// Perform type-specific calculations.
|
||||||
var saddr []byte
|
var saddr []byte
|
||||||
switch decoded.(type) {
|
switch decoded.(type) {
|
||||||
case *util.AddressPubKeyHash:
|
case *util.AddressPublicKey:
|
||||||
saddr = util.TstAddressSAddr(encoded)
|
saddr = util.TstAddressSAddrP2PK(encoded)
|
||||||
|
|
||||||
case *util.AddressScriptHash:
|
case *util.AddressScriptHash:
|
||||||
saddr = util.TstAddressSAddr(encoded)
|
saddr = util.TstAddressSAddrP2SH(encoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check script address, as well as the HashBlake2b method for P2PKH and
|
// Check script address, as well as the HashBlake2b method for P2SH addresses.
|
||||||
// P2SH addresses.
|
|
||||||
if !bytes.Equal(saddr, decoded.ScriptAddress()) {
|
if !bytes.Equal(saddr, decoded.ScriptAddress()) {
|
||||||
t.Errorf("%v: script addresses do not match:\n%x != \n%x",
|
t.Errorf("%v: script addresses do not match:\n%x != \n%x",
|
||||||
test.name, saddr, decoded.ScriptAddress())
|
test.name, saddr, decoded.ScriptAddress())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch a := decoded.(type) {
|
switch a := decoded.(type) {
|
||||||
case *util.AddressPubKeyHash:
|
case *util.AddressPublicKey:
|
||||||
if h := a.HashBlake2b()[:]; !bytes.Equal(saddr, h) {
|
if h := a.ScriptAddress()[:]; !bytes.Equal(saddr, h) {
|
||||||
t.Errorf("%v: hashes do not match:\n%x != \n%x",
|
t.Errorf("%v: hashes do not match:\n%x != \n%x",
|
||||||
test.name, saddr, h)
|
test.name, saddr, h)
|
||||||
return
|
return
|
||||||
@ -357,7 +356,7 @@ func TestDecodeAddressErrorConditions(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"kaspasim:raskzcg58mth0an",
|
"kaspasim:raskzcg58mth0an",
|
||||||
util.Bech32PrefixKaspaSim,
|
util.Bech32PrefixKaspaSim,
|
||||||
"decoded address is of unknown size",
|
"unknown address type",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"kaspatest:qqq65mvpxcmajeq44n2n8vfn6u9f8l4zsy0xez0tzw",
|
"kaspatest:qqq65mvpxcmajeq44n2n8vfn6u9f8l4zsy0xez0tzw",
|
||||||
|
@ -18,14 +18,14 @@ expensive hashing operations.
|
|||||||
Address Overview
|
Address Overview
|
||||||
|
|
||||||
The Address interface provides an abstraction for a kaspa address. While the
|
The Address interface provides an abstraction for a kaspa address. While the
|
||||||
most common type is a pay-to-pubkey-hash, kaspa already supports others and
|
most common type is a pay-to-pubkey, kaspa already supports others and
|
||||||
may well support more in the future. This package currently provides
|
may well support more in the future. This package currently provides
|
||||||
implementations for the pay-to-pubkey-hash, and pay-to-script-hash address
|
implementations for the pay-to-pubkey, and pay-to-script-hash address
|
||||||
types.
|
types.
|
||||||
|
|
||||||
To decode/encode an address:
|
To decode/encode an address:
|
||||||
|
|
||||||
addrString := "kaspa:qqfgqp8l9l90zwetj84k2jcac2m8falvvyy8xjtnhd"
|
addrString := "kaspa:qqj9fg59mptxkr9j0y53j5mwurcmda5mtza9n6v9pm9uj8h0wgk6uma5pvumr"
|
||||||
defaultPrefix := util.Bech32PrefixKaspa
|
defaultPrefix := util.Bech32PrefixKaspa
|
||||||
addr, err := util.DecodeAddress(addrString, defaultPrefix)
|
addr, err := util.DecodeAddress(addrString, defaultPrefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -22,10 +22,10 @@ func TstAppDataDir(goos, appName string, roaming bool) string {
|
|||||||
return appDir(goos, appName, roaming)
|
return appDir(goos, appName, roaming)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TstAddressPubKeyHash(prefix Bech32Prefix, hash [blake2b.Size256]byte) *AddressPubKeyHash {
|
func TstAddressPubKey(prefix Bech32Prefix, hash [PublicKeySize]byte) *AddressPublicKey {
|
||||||
return &AddressPubKeyHash{
|
return &AddressPublicKey{
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
hash: hash,
|
publicKey: hash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,8 +40,15 @@ func TstAddressScriptHash(prefix Bech32Prefix, hash [blake2b.Size256]byte) *Addr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TstAddressSAddr returns the expected script address bytes for
|
// TstAddressSAddr returns the expected script address bytes for
|
||||||
// P2PKH and P2SH kaspa addresses.
|
// P2PK kaspa addresses.
|
||||||
func TstAddressSAddr(addr string) []byte {
|
func TstAddressSAddrP2PK(addr string) []byte {
|
||||||
|
_, decoded, _, _ := bech32.Decode(addr)
|
||||||
|
return decoded[:PublicKeySize]
|
||||||
|
}
|
||||||
|
|
||||||
|
// TstAddressSAddrP2SH returns the expected script address bytes for
|
||||||
|
// P2SH kaspa addresses.
|
||||||
|
func TstAddressSAddrP2SH(addr string) []byte {
|
||||||
_, decoded, _, _ := bech32.Decode(addr)
|
_, decoded, _, _ := bech32.Decode(addr)
|
||||||
return decoded[:blake2b.Size256]
|
return decoded[:blake2b.Size256]
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user