Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: FabioCarpi on December 12, 2014, 10:07:43 PM



Title: sign transaction
Post by: FabioCarpi on December 12, 2014, 10:07:43 PM
could someone indicate me a site that explains step by step how to sign a transaction


Title: Re: sign transaction
Post by: amaclin on December 12, 2014, 10:16:21 PM
could someone indicate me a site that explains step by step how to sign a transaction
Do you need signing with RPC calls? Or signing ECDSA itself?

http://bitcoin.stackexchange.com/questions/3374
http://bitcoin.stackexchange.com/questions/32628


Title: Re: sign transaction
Post by: picolo on December 12, 2014, 11:05:47 PM
could someone indicate me a site that explains step by step how to sign a transaction

It is very simple on the blockchain.info wallet.


Title: Re: sign transaction
Post by: FabioCarpi on December 13, 2014, 12:45:25 AM
Do you need signing with RPC calls? Or signing ECDSA itself?

http://bitcoin.stackexchange.com/questions/3374
http://bitcoin.stackexchange.com/questions/32628
Thanks.
Im a developer...


Title: Re: sign transaction
Post by: dabura667 on December 13, 2014, 02:30:47 AM
Do you need signing with RPC calls? Or signing ECDSA itself?

http://bitcoin.stackexchange.com/questions/3374
http://bitcoin.stackexchange.com/questions/32628
Thanks.
Im a developer...

I highly recommend against writing your own crypto...

What language are you trying to code in?


Title: Re: sign transaction
Post by: fbueller on December 13, 2014, 03:32:09 PM
Your code will need to touch on a lot of things.. Deserialize a transaction, correctly preparing the hash of the input to be signed, implementing the elliptic curve crypto to create keys, sign them, etc (this is actually easy if you find a solid & tested ECC implementation). If possible, you might prefer to implement HMAC_DBRG so you have deterministic signatures so you don't lose your mind! (as ECDSA signatures include a nonce, they can be hard to test)

Most of the prep work for signing is described here: https://en.bitcoin.it/wiki/OP_CHECKSIG


Title: Re: sign transaction
Post by: amaclin on December 13, 2014, 03:44:44 PM
Quote
Your code will need to touch on a lot of things.. Deserialize a transaction, correctly preparing the hash of the input to be signed...

In fact, this is not "a lot of things" if you know what you are want to achive.
For example, this is a piece of my program for "...correctly preparing the hash of the input to be signed..."
I do not want to explain everything but just show you that this is short and easy

Code:
const MyKey32 Transaction::getRawHash ( const int n, const QByteArray& scr ) const
{
  MyByteArray ret;                                     // create empty array
  Stream stream ( s );                               
  ret.putInt32 ( stream.readU32 ( ) );                 // version
  ret.putVarInt ( stream.readVar ( ) );                // input count
  for ( int i ( 0 ); i < inputs; i++ )                 // copy all inputs
  {
    ret.append ( stream.readHash ( ) );                // copy 32 byte hash as is
    ret.putInt32 ( stream.readU32 ( ) );               // copy 4 bytes index
    stream.skipVarData ( );                            // skip original script
    ret.putPrefixed ( i == n ? scr : QByteArray ( ) ); // script replacement
    ret.putInt32 ( stream.readU32 ( ) );
  }
  ret.putVarInt ( stream.readVar ( ) );                // output count
  for ( int i ( 0 ); i < outputs; i++ )                // copy all outputs byte-by-byte
  {
    ret.putInt64 ( stream.readU64 ( ) );
    ret.putPrefixed ( stream.readVarData ( ) );
  }
  ret.putInt32 ( stream.readU32 ( ) );                 // lock
  ret.putInt32 ( SIGHASH_ALL );                        // append hashcode
  return MyKey32 ( ret.constData ( ), ret.size ( ) );  // create hash256 of array
}


Title: Re: sign transaction
Post by: Ume on December 13, 2014, 03:47:39 PM
otherwise juxt go to bc and custom send and sign a message :P  ;D ;D


Title: Re: sign transaction
Post by: CIYAM on December 13, 2014, 03:49:40 PM
For a more fleshed out version that is still fairly easy to follow:

https://github.com/ciyam/ciyam/blob/master/src/crypto_keys.cpp#L761

(it includes support for an optional OP_RETURN *message*)


Title: Re: sign transaction
Post by: FabioCarpi on December 14, 2014, 07:58:20 PM
thank you all
im developing in php..
my purpose its only understand the code (https://github.com/FabioCarpi/MyCoin)
i understand better write my onw code (i like to reinvent the wheel)
and the php its the only language i still know (sorry its a shame for me....)


Title: Re: sign transaction
Post by: Buffer Overflow on December 18, 2014, 10:15:04 AM
thank you all
im developing in php..
my purpose its only understand the code (https://github.com/FabioCarpi/MyCoin)
i understand better write my onw code (i like to reinvent the wheel)
and the php its the only language i still know (sorry its a shame for me....)

In your database tables I noticed you are using VARCHAR(65) for hashes. You might as well use BINARY(32).


Title: Re: sign transaction
Post by: FabioCarpi on December 19, 2014, 08:33:58 PM
In your database tables I noticed you are using VARCHAR(65) for hashes. You might as well use BINARY(32).
thanks for the tip


Title: Re: sign transaction
Post by: fbueller on December 20, 2014, 10:45:06 AM
This is part of a work in progress, but is PHP, so should help! I have yet to release the rest of the library. The other sighashtypes have not been tested yet.

Code:
<?php
namespace Bitcoin\Signature;
use 
Bitcoin\Crypto\Hash;
use 
Bitcoin\Util\Buffer;
use 
Bitcoin\Util\Parser;
use 
Bitcoin\Script\Script;
use 
Bitcoin\Transaction\TransactionInterface;
use 
Bitcoin\Transaction\TransactionOutputInterface;
/**
 * Class SigHashBuilder
 * @package Bitcoin
 */
class SignatureHash implements SignatureHashInterface
{
    
/**
     * @var TransactionInterface
     */
    
protected $transaction;
    
/**
     * @var TransactionInterface
     */
    
protected $copy;
    
/**
     * @param TransactionInterface $transaction
     */
    
public function __construct(TransactionInterface $transaction)
    {
        
$this->transaction $transaction;
    }
    
/**
     * @return TransactionInterface
     */
    
public function getTransaction()
    {
        return 
$this->transaction;
    }
    
/**
     * Calculate the hash of the current transaction, when you are looking to
     * spend $txOut, and are signing $inputToSign. The SigHashType defaults to
     * SIGHASH_ALL, though SIGHASH_SINGLE, SIGHASH_NONE, SIGHASH_ANYONECANPAY
     * can be used.
     *
     * @param TransactionOutputInterface $txOut
     * @param $inputToSign
     * @param int $sighashType
     * @return Buffer
     * @throws \Exception
     */
    
public function calculateHash(TransactionOutputInterface $txOut$inputToSign$sighashType SignatureHashInterface::SIGHASH_ALL)
    {
        
$this->copy     =  $this->getTransaction();
        
$inputs         = &$this->copy->getInputsReference();
        
$outputs        = &$this->copy->getOutputsReference();
        if (
$inputToSign count($inputs)) {
            throw new \
Exception('Input does not exist');
        }
        
// Default SIGHASH_ALL procedure: null all input scripts
        
for ($i 0$i count($inputs); $i++) {
            
$inputs[$i]->setScriptBuf(new Buffer());
        }
        
$inputs[$inputToSign]->setScript($txOut->getScript());
        if (
$sighashType 31 == SignatureHashInterface::SIGHASH_NONE) {
            
// Set outputs to empty vector, and set sequence number of inputs to 0.
            
$outputs = array();
            for (
$i 0$i count($inputs); $i++) {
                if (
$i != $inputToSign) {
                    
$inputs[$i]->setSequence(0);
                }
            }
        } else if (
$sighashType 31 == SignatureHashInterface::SIGHASH_SINGLE) {
            
// Resize output array to $inputToSign + 1, set remaining scripts to null,
            // and set sequence's to zero.
            
$nOutput $inputToSign;
            if (
$nOutput >= count($outputs)) {
                throw new \
Exception("SignatureHash->calculateHash(): nOutput $nOutput is out of range");
            }
            
// Resize..
            
$outputs array_slice($outputs0, ($nOutput+1));
            
// Set to null
            
for ($i 0$i $nOutput$i++) {
                
$outputs[$i]->setScript(new Script());
            }
            
// Let the others update at will
            
for ($i 0$i count($outputs); $i++) {
                if (
$i != $inputToSign) {
                    
$inputs[$i]->setSequence(0);
                }
            }
        }
        
// This can happen regardless of whether it's ALL, NONE, or SINGLE
        
if ($sighashType 31 == SignatureHashInterface::SIGHASH_ANYONECANPAY) {
            
$input  $inputs[$inputToSign];
            
$inputs = array($input);
        }
        
// Serialize the TxCopy and append the 4 byte hashtype (little endian);
        
$txParser = new Parser($this->copy->serialize('hex'));
        
$txParser->writeInt(4$sighashTypetrue);
        
$hash     Hash::sha256d($txParser->getBuffer()->serialize());
        
$buffer   Buffer::hex($hash);
        return 
$buffer;
    }
}