Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Script was NOT verified successfully #19

Closed
timigod opened this issue Jul 23, 2020 · 3 comments
Closed

Error: Script was NOT verified successfully #19

timigod opened this issue Jul 23, 2020 · 3 comments

Comments

@timigod
Copy link

timigod commented Jul 23, 2020

I'm unable to successfully [sign and] send a transaction using this library. I keep getting the error:

HTTP 400 Bad Request, Message(s): Error validating generated transaction: Error running script for input 0 referencing 97043eae569096c8435a431a6a0b1751a9aee08851abf318a8d8dcbe35e56063 at 0: Script was NOT verified successfully.

I'm essentially following the example in the docs with a few differences. I'm using an HD (BIP 84) Wallet.

I'm sure I'm signing with the correct private key (in the hex format), I'm able to derive [the input] addresses returned as part of the TxSkel that's returned to me using the same private keys that I use to sign the transaction.

Here's a snippet of the code:

walletName := os.Getenv("WALLET_NAME")
btcAmount, _ := btcutil.NewAmount(txRequest.Amount)
satoshiAmount := int(btcAmount.ToUnit(btcutil.AmountSatoshi))
input := gobcy.TXInput{
	WalletName: walletName,
}
output := gobcy.TXOutput{Value: satoshiAmount, Addresses: []string{txRequest.RecipientAddress}}
tempTx := gobcy.TX{Inputs: []gobcy.TXInput{input}, Outputs: []gobcy.TXOutput{output}}
skeleton, err := blockCypherClient(txRequest.CurrencyIso).NewTX(tempTx, false)

if err != nil {
	log.Printf("%+v", err)
}
log.Printf("%+v", skeleton.Trans)
// Output: 2020/07/23 01:04:57 {BlockHash: BlockHeight:-1 Hash:a6d523fedc8dfcf003278640d9a6daf9dd8920cd5dca926f2d3a40247c25938d Addresses:[bc1q26w9elz890cj0tcwfvut6uqaez6gk7hkm727pc 34oefDtSVSdiEoVgikXkyemgKXkQnZ8QZS] Total:100000 Fees:10000 Size:124 Preference:high RelayedBy:41.184.252.142 Received:2020-07-23 00:04:57.546679367 +0000 UTC Confirmed:0001-01-01 00:00:00 +0000 UTC Confirmations:0 Confidence:0 Ver:1 LockTime:0 DoubleSpend:false DoubleOf: ReceiveCount:0 VinSize:2 VoutSize:1 Hex: DataProtocol: ChangeAddress: NextInputs: NextOutputs: Inputs:[{PrevHash:97043eae569096c8435a431a6a0b1751a9aee08851abf318a8d8dcbe35e56063 OutputIndex:0 OutputValue:100000 Addresses:[bc1q26w9elz890cj0tcwfvut6uqaez6gk7hkm727pc] Sequence:4294967295 ScriptType:pay-to-witness-pubkey-hash Script: Age:640274 WalletName:} {PrevHash:7e85fae44ff92e53e9316b9e09bdee8d53f848ad13b355992b460cafa7556e59 OutputIndex:0 OutputValue:10000 Addresses:[bc1q26w9elz890cj0tcwfvut6uqaez6gk7hkm727pc] Sequence:4294967295 ScriptType:pay-to-witness-pubkey-hash Script: Age:640275 WalletName:}] Outputs:[{SpentBy: Value:100000 Addresses:[34oefDtSVSdiEoVgikXkyemgKXkQnZ8QZS] ScriptType:pay-to-script-hash Script:a914222989e5ecdf370e31faf7f0175240c094c3f78387 DataHex: DataString:}]}


var privateKeys []string
for _, input := range skeleton.Trans.Inputs {
	address := models.Address{}        

	DB.Where("value = ?", input.Addresses[0]).First(&address)
	privateKey := getAddressPrivateKey(address) // this is how I generate the hex private key. Function code below
	privateKeys = append(privateKeys, privateKey)
}

err = skeleton.Sign(privateKeys)
if err != nil {
	log.Printf("%+v", err)
}
skeleton, err = blockCypherClient(txRequest.CurrencyIso).SendTX(skeleton)
if err != nil {
	log.Println(err) 
        // Output: HTTP 400 Bad Request, Message(s): Error validating generated transaction: Error running script for input 0 referencing 97043eae569096c8435a431a6a0b1751a9aee08851abf318a8d8dcbe35e56063 at 0: Script was NOT verified successfully.
}

Here are the functions I use to generate the private key(s):

func getKeyAccounts() (publicKeyAccount, privateKeyAccount *bip32.Key) {
	mnemonic := os.Getenv("SEED_PHRASE")
	seed := bip39.NewSeed(mnemonic, "")

	// create a master Key from mnemonic seed
	masterPrivateKey, _ := bip32.NewMasterKey(seed)
	masterPrivateKey.Version = Bip84PrivateWalletVersion
	masterPublicKey := masterPrivateKey.PublicKey()
	masterPublicKey.Version = Bip84PublicWalletVersion

	// Generate a BIP84 path key derivation
	purposeChildKey, _ := masterPrivateKey.NewChildKey(PurposeBIP84)
	coinTypeChildKey, _ := purposeChildKey.NewChildKey(CoinTypeBTC)

	// generate first child account of m/84'/0'/0'
	childAccount, _ := coinTypeChildKey.NewChildKey(0 + Apostrophe)
	childAccount.Version = Bip84PrivateWalletVersion
	childAccountPublicKey := childAccount.PublicKey()

	return childAccountPublicKey, childAccount
}

func getAddressPrivateKey(address models.Address) string {
	path := address.Path // I save the path as a string in my database. It's in the format m/0/1, m/0/2...etc
	pathSlice := strings.Split(path, "/")
	_, extendedPrivateKeyAccount := getKeyAccounts()

	firstChildIdx64, _ := strconv.ParseUint(pathSlice[1], 10, 32)
	firstChildIdx32 := uint32(firstChildIdx64)

	firstChild, _ := extendedPrivateKeyAccount.NewChildKey(firstChildIdx32) // to get the m/0 child

	secondChildIdx64, _ := strconv.ParseUint(pathSlice[2], 10, 32)
	secondChildIdx32 := uint32(secondChildIdx64)

	secondChild, _ := firstChild.NewChildKey(secondChildIdx32) // to get m/0/i child

	prvKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), secondChild.Key)
	btcwif, _ := btcutil.NewWIF(prvKey, &chaincfg.MainNetParams, true)
	privateKeyHex := hex.EncodeToString(btcwif.PrivKey.D.Bytes()) // sure this is the correct hex private key. I can always find my way back to correct the input address with this string
	return privateKeyHex 
}
@quentinlesceller
Copy link
Contributor

  1. Can you add the SIGHASH_ALL marker (01 byte) at the end of the signature.
  2. If 1 doesn't work can you provide me with an example that I can run?

@timigod
Copy link
Author

timigod commented Jul 23, 2020

@quentinlesceller I did that and it worked. Thanks a lot.

@quentinlesceller
Copy link
Contributor

We are probably going to add the sighashall by default in the coming weeks. Thank you for your patience!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants