Author

Topic: sign transaction (Read 1794 times)

sr. member
Activity: 412
Merit: 266
December 20, 2014, 06:45:06 AM
#13
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:
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;
    }
}
sr. member
Activity: 375
Merit: 254
December 19, 2014, 04:33:58 PM
#12
In your database tables I noticed you are using VARCHAR(65) for hashes. You might as well use BINARY(32).
thanks for the tip
legendary
Activity: 1652
Merit: 1015
December 18, 2014, 06:15:04 AM
#11
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).
sr. member
Activity: 375
Merit: 254
December 14, 2014, 03:58:20 PM
#10
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....)
legendary
Activity: 1890
Merit: 1072
Ian Knowles - CIYAM Lead Developer
December 13, 2014, 11:49:40 AM
#9
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*)
Ume
full member
Activity: 210
Merit: 100
Finding oNlinE JoB ---=== :)
December 13, 2014, 11:47:39 AM
#8
otherwise juxt go to bc and custom send and sign a message Tongue  Grin Grin
legendary
Activity: 1260
Merit: 1019
December 13, 2014, 11:44:44 AM
#7
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
}
sr. member
Activity: 412
Merit: 266
December 13, 2014, 11:32:09 AM
#6
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
sr. member
Activity: 475
Merit: 252
December 12, 2014, 10:30:47 PM
#5

I highly recommend against writing your own crypto...

What language are you trying to code in?
sr. member
Activity: 375
Merit: 254
December 12, 2014, 08:45:25 PM
#4
hero member
Activity: 1022
Merit: 500
December 12, 2014, 07:05:47 PM
#3
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.
legendary
Activity: 1260
Merit: 1019
December 12, 2014, 06:16:21 PM
#2
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
sr. member
Activity: 375
Merit: 254
December 12, 2014, 06:07:43 PM
#1
could someone indicate me a site that explains step by step how to sign a transaction
Jump to: