Пример #1
0
int serialize_tx(struct buff *buf, const btc_msg_tx *tx) {
  uint64 i;
  int res;

  res = serialize_uint32(buf, tx->version);
  res |= serialize_varint(buf, tx->in_count);

  for (i = 0; i < tx->in_count; i++) {
    res |= serialize_uint256(buf, &tx->tx_in[i].prevTxHash);
    res |= serialize_uint32(buf, tx->tx_in[i].prevTxOutIdx);
    res |= serialize_varint(buf, tx->tx_in[i].scriptLength);
    res |=
        serialize_bytes(buf, tx->tx_in[i].scriptSig, tx->tx_in[i].scriptLength);
    res |= serialize_uint32(buf, tx->tx_in[i].sequence);
  }

  res |= serialize_varint(buf, tx->out_count);

  for (i = 0; i < tx->out_count; i++) {
    res |= serialize_uint64(buf, tx->tx_out[i].value);
    res |= serialize_varint(buf, tx->tx_out[i].scriptLength);
    res |= serialize_bytes(buf, tx->tx_out[i].scriptPubKey,
                           tx->tx_out[i].scriptLength);
  }

  res |= serialize_uint32(buf, tx->lock_time);

  return res;
}
Пример #2
0
/* Serialize a block into a flat array (for hashing or writing to a file). */
static void block_serialize(const struct block *b, unsigned char buf[SERIALIZED_BLOCK_LEN])
{
	unsigned char *p, *endp;
	unsigned char uint32_buf[4];

	p = buf;
	endp = buf + SERIALIZED_BLOCK_LEN;
	serialize(&p, endp, b->prev_block_hash, sizeof(b->prev_block_hash));
	serialize_uint32(uint32_buf, b->height);
	serialize(&p, endp, uint32_buf, sizeof(uint32_buf));
	serialize_uint32(uint32_buf, b->nonce);
	serialize(&p, endp, uint32_buf, sizeof(uint32_buf));
	serialize_uint32(uint32_buf, b->reward_tx.height);
	serialize(&p, endp, uint32_buf, sizeof(uint32_buf));
	serialize(&p, endp, b->reward_tx.prev_transaction_hash, sizeof(b->reward_tx.prev_transaction_hash));
	serialize(&p, endp, b->reward_tx.dest_pubkey.x, sizeof(b->reward_tx.dest_pubkey.x));
	serialize(&p, endp, b->reward_tx.dest_pubkey.y, sizeof(b->reward_tx.dest_pubkey.y));
	serialize(&p, endp, b->reward_tx.src_signature.r, sizeof(b->reward_tx.src_signature.r));
	serialize(&p, endp, b->reward_tx.src_signature.s, sizeof(b->reward_tx.src_signature.s));
	serialize_uint32(uint32_buf, b->normal_tx.height);
	serialize(&p, endp, uint32_buf, sizeof(uint32_buf));
	serialize(&p, endp, b->normal_tx.prev_transaction_hash, sizeof(b->normal_tx.prev_transaction_hash));
	serialize(&p, endp, b->normal_tx.dest_pubkey.x, sizeof(b->normal_tx.dest_pubkey.x));
	serialize(&p, endp, b->normal_tx.dest_pubkey.y, sizeof(b->normal_tx.dest_pubkey.y));
	serialize(&p, endp, b->normal_tx.src_signature.r, sizeof(b->normal_tx.src_signature.r));
	serialize(&p, endp, b->normal_tx.src_signature.s, sizeof(b->normal_tx.src_signature.s));
	if (p != endp)
		abort();
}
Пример #3
0
int serialize_msgheader(struct buff *buf, const btc_msg_header *h) {
  int res;

  res = serialize_uint32(buf, h->magic);
  res |= serialize_bytes(buf, h->message, ARRAYSIZE(h->message));
  res |= serialize_uint32(buf, h->payloadLength);
  res |= serialize_bytes(buf, h->checksum, ARRAYSIZE(h->checksum));

  ASSERT_NOT_TESTED(res == 0);

  return res;
}
Пример #4
0
bool serialize_data(char *&r_stream, uint32_t &r_stream_size, uint32_t &r_offset, const void *p_data, uint32_t p_data_size)
{
	if (serialize_uint32(r_stream, r_stream_size, r_offset, p_data_size) &&
		serialize_bytes(r_stream, r_stream_size, r_offset, p_data, p_data_size))
		return true;
	return false;
}
Пример #5
0
int serialize_version(struct buff *buf, const btc_msg_version *v) {
  int res;

  res = serialize_uint32(buf, v->version);
  res |= serialize_uint64(buf, v->services);
  res |= serialize_uint64(buf, v->time);

  res |= serialize_addr(buf, &v->addrTo);
  res |= serialize_addr(buf, &v->addrFrom);

  res |= serialize_uint64(buf, v->nonce);
  res |= serialize_str(buf, v->strVersion);
  res |= serialize_uint32(buf, v->startingHeight);

  return res;
}
Пример #6
0
int serialize_varint(struct buff *buf, const uint64 val) {
  int res;
  uint8 c;

  if (val < 253) {
    c = val;
    return serialize_uint8(buf, c);
  } else if (val < 0x10000) {
    uint16 len16 = val;
    c = 253;
    res = serialize_uint8(buf, c);
    if (res) {
      return res;
    }
    return serialize_uint16(buf, len16);
  } else {
    uint32 len32 = val;
    c = 254;
    res = serialize_uint8(buf, c);
    if (res) {
      return res;
    }
    return serialize_uint32(buf, len32);
  }
}
Пример #7
0
int serialize_inv(struct buff *buf, const btc_msg_inv *inv) {
  int res;

  res = serialize_uint32(buf, inv->type);
  res |= serialize_bytes(buf, &inv->hash, sizeof inv->hash);

  return res;
}
Пример #8
0
int serialize_blocklocator(struct buff *buf, const btc_block_locator *bl) {
  int res;
  int i;

  res = serialize_uint32(buf, bl->protversion);
  res |= serialize_varint(buf, bl->numHashes);
  for (i = 0; i < bl->numHashes; i++) {
    res |= serialize_uint256(buf, &bl->hashArray[i]);
  }
  res |= serialize_uint256(buf, &bl->hashStop);

  return res;
}
Пример #9
0
/* Sign this transaction using the given private key. Returns 1 for success; 0
 * for error. */
int transaction_sign(struct transaction *tx, EC_KEY *key)
{
	unsigned char uint32_buf[4];
	SHA256_CTX sha;
	ECDSA_SIG *sig;
	BIGNUM *x, *y;
	hash_output h;

	sig = NULL;
	x = NULL;
	y = NULL;

	/* Signing this transaction, we ignore the src_signature field
	 * itself. */
	SHA256_Init(&sha);
	serialize_uint32(uint32_buf, tx->height);
	SHA256_Update(&sha, uint32_buf, sizeof(uint32_buf));
	SHA256_Update(&sha, tx->prev_transaction_hash, sizeof(tx->prev_transaction_hash));
	SHA256_Update(&sha, tx->dest_pubkey.x, sizeof(tx->dest_pubkey.x));
	SHA256_Update(&sha, tx->dest_pubkey.y, sizeof(tx->dest_pubkey.y));
	SHA256_Final(h, &sha);

	sig = ECDSA_do_sign(h, sizeof(h), key);
	if (sig == NULL)
		goto err;

	/* Copy the signature into the transaction's byte arrays. */
	memset(tx->src_signature.r, 0, sizeof(tx->src_signature.r));
	memset(tx->src_signature.s, 0, sizeof(tx->src_signature.s));
	if (bn2bin(sig->r, tx->src_signature.r, sizeof(tx->src_signature.r)) != 1)
		goto err;
	if (bn2bin(sig->s, tx->src_signature.s, sizeof(tx->src_signature.s)) != 1)
		goto err;

	ECDSA_SIG_free(sig);
	BN_free(x);
	BN_free(y);

	return 1;

err:
	if (sig != NULL)
		ECDSA_SIG_free(sig);
	if (x != NULL)
		BN_free(x);
	if (y != NULL)
		BN_free(y);

	return 0;
}
Пример #10
0
static void script_tx_sighash(struct wallet *wallet, uint256 *hash,
                              const struct buff *scriptPubKey,
                              const struct btc_msg_tx *tx, uint32 idx,
                              enum script_hash_type hashType) {
  struct btc_msg_tx *tx2;
  struct buff *buf;
  int i;

  ASSERT(idx < tx->in_count);

  memset(hash, 0, sizeof *hash);
  tx2 = btc_msg_tx_dup(tx);

  Log(LGPFX " Computing sighash for txi-%u/%llu\n", idx, tx2->in_count);

  /*
   * Zero-out all the inputs' signatures.
   */
  for (i = 0; i < tx2->in_count; i++) {
    tx2->tx_in[i].scriptLength = 0;
  }

  size_t len = buff_maxlen(scriptPubKey);
  ASSERT(len > 0);

  ASSERT(tx2->tx_in[idx].scriptSig == NULL);
  ASSERT(tx2->tx_in[idx].scriptLength == 0);

  tx2->tx_in[idx].scriptLength = len;
  tx2->tx_in[idx].scriptSig = safe_malloc(len);

  memcpy(tx2->tx_in[idx].scriptSig, buff_base(scriptPubKey), len);

  ASSERT((hashType & 0x1f) == SIGHASH_ALL);

  /*
   * Final step:
   *
   * Serialize tx + hashType (as a uint32) and compute hash.
   */

  buf = buff_alloc();
  serialize_tx(buf, tx2);
  serialize_uint32(buf, hashType);
  hash256_calc(buff_base(buf), buff_curlen(buf), hash);
  buff_free(buf);

  btc_msg_tx_free(tx2);
  free(tx2);
}
Пример #11
0
/* Compute the hash value of this transaction. */
void transaction_hash(const struct transaction *tx, hash_output h)
{
	unsigned char uint32_buf[4];
	SHA256_CTX sha;

	SHA256_Init(&sha);
	serialize_uint32(uint32_buf, tx->height);
	SHA256_Update(&sha, uint32_buf, sizeof(uint32_buf));
	SHA256_Update(&sha, tx->prev_transaction_hash, sizeof(tx->prev_transaction_hash));
	SHA256_Update(&sha, tx->dest_pubkey.x, sizeof(tx->dest_pubkey.x));
	SHA256_Update(&sha, tx->dest_pubkey.y, sizeof(tx->dest_pubkey.y));
	SHA256_Update(&sha, tx->src_signature.r, sizeof(tx->src_signature.r));
	SHA256_Update(&sha, tx->src_signature.s, sizeof(tx->src_signature.s));
	SHA256_Final(h, &sha);
}
Пример #12
0
static void script_push_data(struct buff *buf, const void *data, size_t len) {
  ASSERT(buf->grow);

  Log("%s: len=%zu / %#zx\n", __FUNCTION__, len, len);

  if (len < OP_PUSHDATA1) {
    serialize_uint8(buf, len);
  } else if (len <= 0xff) {
    serialize_uint8(buf, OP_PUSHDATA1);
    serialize_uint8(buf, len);
  } else if (len <= 0xffff) {
    serialize_uint8(buf, OP_PUSHDATA2);
    serialize_uint16(buf, len);
  } else {
    serialize_uint8(buf, OP_PUSHDATA4);
    serialize_uint32(buf, len);
  }
  serialize_bytes(buf, data, len);
}
Пример #13
0
void serialize_header(pokeheader *header, char **outstream)
{
	char buff8;
	char buff8b;
	char *buff32 = ( char *) malloc(4*sizeof( char));

	buff32 = serialize_uint32(buff32, header->type);
	buff8 = serialize_uint8(buff8, header->id);
	buff8b = serialize_uint8(buff8b, header->data_size);

	char *instream = ( char *) malloc(7* sizeof( char));
	for(int i = 0; i< 4; i++){
		instream[i] = buff32[i];
 	}

	instream[4] = buff8;
	instream[5] = buff8b;

	memcpy(*outstream, instream, 7 );

	free(buff32);
	free(instream);

}
Пример #14
0
/* Verify the signature on this transaction using the public key
 * prev_tx->dest_pubkey. The return value is:
 *  1 for successful verification;
 *  0 for failed verification;
 * -1 for any runtime error. */
int transaction_verify(struct transaction *tx, const struct transaction *prev_tx)
{
	unsigned char uint32_buf[4];
	SHA256_CTX sha;
	hash_output h;
	EC_KEY *pubkey;
	ECDSA_SIG *sig;
	BIGNUM *x, *y;
	int v, rc;

	pubkey = NULL;
	sig = NULL;
	x = NULL;
	y = NULL;

	SHA256_Init(&sha);
	serialize_uint32(uint32_buf, tx->height);
	SHA256_Update(&sha, uint32_buf, sizeof(uint32_buf));
	SHA256_Update(&sha, tx->prev_transaction_hash, sizeof(tx->prev_transaction_hash));
	SHA256_Update(&sha, tx->dest_pubkey.x, sizeof(tx->dest_pubkey.x));
	SHA256_Update(&sha, tx->dest_pubkey.y, sizeof(tx->dest_pubkey.y));
	SHA256_Final(h, &sha);

	x = BN_bin2bn(prev_tx->dest_pubkey.x, sizeof(prev_tx->dest_pubkey.x), NULL);
	if (x == NULL)
		goto err;
	y = BN_bin2bn(prev_tx->dest_pubkey.y, sizeof(prev_tx->dest_pubkey.y), NULL);
	if (y == NULL)
		goto err;

	pubkey = EC_KEY_new_by_curve_name(EC_GROUP_NID);
	if (pubkey == NULL)
		goto err;
	rc = EC_KEY_set_public_key_affine_coordinates(pubkey, x, y);
	if (rc != 1) {
		EC_KEY_free(pubkey);
		BN_free(x);
		BN_free(y);
		return 0;
	}

	BN_free(x);
	x = NULL;
	BN_free(y);
	y = NULL;

	sig = ECDSA_SIG_new();
	if (sig == NULL)
		goto err;

	sig->r = BN_bin2bn(tx->src_signature.r, sizeof(tx->src_signature.r), sig->r);
	if (sig->r == NULL)
		goto err;
	sig->s = BN_bin2bn(tx->src_signature.s, sizeof(tx->src_signature.s), sig->s);
	if (sig->s == NULL)
		goto err;

	v = ECDSA_do_verify(h, sizeof(h), sig, pubkey);

	EC_KEY_free(pubkey);
	ECDSA_SIG_free(sig);

	return v;

err:
	if (pubkey != NULL)
		EC_KEY_free(pubkey);
	if (sig != NULL)
		ECDSA_SIG_free(sig);
	if (x != NULL)
		BN_free(x);
	if (y != NULL)
		BN_free(y);

	return -1;
}