operation::stack operation::to_pay_multisig_pattern(uint8_t signatures, const std::vector<data_chunk>& points) { static constexpr size_t op_1 = static_cast<uint8_t>(opcode::op_1); static constexpr size_t op_16 = static_cast<uint8_t>(opcode::op_16); static constexpr size_t zero = op_1 - 1; static constexpr size_t max = op_16 - zero; const auto m = signatures; const auto n = points.size(); if (m < 1 || m > n || n < 1 || n > max) return operation::stack(); const auto op_m = static_cast<opcode>(m + zero); const auto op_n = static_cast<opcode>(points.size() + zero); operation::stack ops; ops.push_back({ op_m, data_chunk() }); for (const auto point: points) { if (!is_point(point)) return operation::stack(); ops.push_back({ opcode::special, point }); } ops.push_back({ op_n, data_chunk() }); ops.push_back({ opcode::checkmultisig, data_chunk() }); return ops; }
operation::stack operation::to_pay_script_hash_pattern(const short_hash& hash) { return operation::stack { operation{ opcode::hash160, data_chunk() }, operation{ opcode::special, to_chunk(hash) }, operation{ opcode::equal, data_chunk() } }; }
operation::stack operation::to_pay_key_hash_pattern(const short_hash& hash) { return operation::stack { operation{ opcode::dup, data_chunk() }, operation{ opcode::hash160, data_chunk() }, operation{ opcode::special, to_chunk(hash) }, operation{ opcode::equalverify, data_chunk() }, operation{ opcode::checksig, data_chunk() } }; }
data_chunk elliptic_curve_key::public_key() const { // same as get_private_key int length = i2o_ECPublicKey(key_, NULL); if (!length) return data_chunk(); data_chunk pubkey(length, 0); uint8_t* pubkey_begin = pubkey.data(); if (i2o_ECPublicKey(key_, &pubkey_begin) != length) return data_chunk(); return pubkey; }
data_chunk decode_base58(std::string encoded) { // Trim spaces and newlines around the string. boost::algorithm::trim(encoded); size_t leading_zeros = count_leading_zeros(encoded); // log(58) / log(256), rounded up. const size_t data_size = encoded.size() * 733 / 1000 + 1; // Allocate enough space in big-endian base256 representation. data_chunk data(data_size); // Process the characters. for (auto it = encoded.begin() + leading_zeros; it != encoded.end(); ++it) { size_t carry = base58_chars.find(*it); if (carry == std::string::npos) return data_chunk(); unpack_char(data, carry); } // Skip leading zeroes in data. auto first_nonzero = search_first_nonzero(data); // Copy result into output vector. data_chunk decoded; const size_t estimated_size = leading_zeros + (data.end() - first_nonzero); decoded.reserve(estimated_size); decoded.assign(leading_zeros, 0x00); decoded.insert(decoded.end(), first_nonzero, data.cend()); return decoded; }
block_type genesis_block() { block_type genesis; genesis.version = 1; genesis.previous_block_hash = null_hash; genesis.merkle = hash_digest{0x4a, 0x5e, 0x1e, 0x4b, 0xaa, 0xb8, 0x9f, 0x3a, 0x32, 0x51, 0x8a, 0x88, 0xc3, 0x1b, 0xc8, 0x7f, 0x61, 0x8f, 0x76, 0x67, 0x3e, 0x2c, 0xc7, 0x7a, 0xb2, 0x12, 0x7b, 0x7a, 0xfd, 0xed, 0xa3, 0x3b}; genesis.timestamp = 1231006505; genesis.bits = 0x1d00ffff; genesis.nonce = 2083236893; transaction_type coinbase_tx; coinbase_tx.version = 1; coinbase_tx.locktime = 0; transaction_input_type coinbase_input; coinbase_input.previous_output.hash = null_hash; coinbase_input.previous_output.index = std::numeric_limits<uint32_t>::max(); // The Times 03/Jan/2009 Chancellor on brink of second bailout for banks coinbase_input.input_script = coinbase_script( data_chunk{0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73}); coinbase_input.sequence = std::numeric_limits<uint32_t>::max(); coinbase_tx.inputs.push_back(coinbase_input); transaction_output_type coinbase_output; coinbase_output.value = coin_price(50); coinbase_output.output_script.push_operation( operation{opcode::special, data_chunk{0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f}}); coinbase_output.output_script.push_operation( operation{opcode::checksig, data_chunk()}); coinbase_tx.outputs.push_back(coinbase_output); genesis.transactions.push_back(coinbase_tx); BITCOIN_ASSERT(genesis.transactions.size() == 1); BITCOIN_ASSERT( generate_merkle_root(genesis.transactions) == genesis.merkle); return genesis; }
data_chunk pubkey_from_secret(const secret_parameter& secret) { elliptic_curve_key privkey; if (!privkey.set_secret(secret)) return data_chunk(); return privkey.public_key(); }
data_chunk sign(ec_secret secret, hash_digest hash, ec_secret nonce) { std::reverse(hash.begin(), hash.end()); init.init(); int out_size = 72; data_chunk signature(out_size); if (!verify_private_key(nonce)) // Needed because of upstream bug return data_chunk(); bool valid = secp256k1_ecdsa_sign(hash.data(), hash.size(), signature.data(), &out_size, secret.data(), nonce.data()) == 1; if (!valid) return data_chunk(); signature.resize(out_size); return signature; }
data_chunk create_address_key(const script& output_script) { payment_address address; if (!extract(address, output_script)) return data_chunk(); serializer serial; serial.write_byte(address.version()); serial.write_short_hash(address.hash()); return serial.data(); }
operation::stack operation::to_null_data_pattern(data_slice data) { if (data.size() > max_null_data_size) return operation::stack(); return operation::stack { operation{ opcode::return_, data_chunk() }, operation{ opcode::special, to_chunk(data) } }; }
operation::stack operation::to_pay_public_key_pattern(data_slice point) { if (!is_point(point)) return operation::stack(); return operation::stack { operation{ opcode::special, to_chunk(point) }, operation{ opcode::checksig, data_chunk() } }; }
data_chunk elliptic_curve_key::sign(hash_digest hash) const { BITCOIN_ASSERT(key_ != nullptr); // SSL likes a reversed hash std::reverse(hash.begin(), hash.end()); data_chunk signature(ECDSA_size(key_)); unsigned int signature_length = signature.size(); if (!ECDSA_sign(0, hash.data(), hash.size(), signature.data(), &signature_length, key_)) return data_chunk(); signature.resize(signature_length); return signature; }
bool unwrap(uint8_t& version, data_chunk& payload, uint32_t& checksum, data_slice wrapped) { constexpr size_t version_length = sizeof(version); constexpr size_t checksum_length = sizeof(checksum); // guard against insufficient buffer length if (wrapped.size() < version_length + checksum_length) return false; if (!verify_checksum(wrapped)) return false; // set return values version = wrapped.data()[0]; payload = data_chunk(wrapped.begin() + version_length, wrapped.end() - checksum_length); const auto checksum_start = wrapped.end() - checksum_length; auto deserial = make_deserializer(checksum_start, wrapped.end()); checksum = deserial.read_4_bytes(); return true; }
data_chunk decode_hex(std::string hex_str) { // Trim the fat. boost::algorithm::trim(hex_str); data_chunk result(hex_str.size() / 2); for (size_t i = 0; i + 1 < hex_str.size(); i += 2) { BITCOIN_ASSERT(hex_str.size() - i >= 2); auto byte_begin = hex_str.begin() + i; auto byte_end = hex_str.begin() + i + 2; // Perform conversion. int val = -1; std::stringstream converter; converter << std::hex << std::string(byte_begin, byte_end); converter >> val; if (val == -1) return data_chunk(); BITCOIN_ASSERT(val <= 0xff); // Set byte. result[i / 2] = val; } return result; }
void append_str(czmqpp::message& message, const std::string& command) { message.append(data_chunk(command.begin(), command.end())); }
data_chunk read_raw_script(const InOut& inout) { const std::string& script_str = inout.script(); return data_chunk(script_str.begin(), script_str.end()); }
data_chunk writable_data_type::data() const { std::string raw_depth(reinterpret_cast<const char*>( dbt_.get_data()), dbt_.get_size()); return data_chunk(raw_depth.begin(), raw_depth.end()); }
uint32_t recreate_height(const Data& raw_data) { const uint8_t* start = reinterpret_cast<const uint8_t*>(raw_data.data()); const uint8_t* end = start + raw_data.size(); return cast_chunk<uint32_t>(data_chunk(start, end)); }
data_chunk StringMessage::doSerialize() const { return data_chunk(this->data(), this->data() + this->size()); }