#420 ethereum unit tests #726
4 changed files with 282 additions and 46 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#include <graphene/peerplays_sidechain/ethereum/transaction.hpp>
|
||||
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
|
|
@ -12,7 +13,6 @@
|
|||
|
||||
#include <graphene/peerplays_sidechain/ethereum/decoders.hpp>
|
||||
#include <graphene/peerplays_sidechain/ethereum/encoders.hpp>
|
||||
#include <graphene/peerplays_sidechain/ethereum/types.hpp>
|
||||
#include <graphene/peerplays_sidechain/ethereum/utils.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain { namespace ethereum {
|
||||
|
|
@ -24,6 +24,16 @@ const secp256k1_context *eth_context() {
|
|||
|
||||
//! transaction
|
||||
|
||||
base_transaction::base_transaction(const std::string &raw_tx) {
|
||||
}
|
||||
|
||||
//! transaction
|
||||
|
||||
transaction::transaction(const std::string &raw_tx) :
|
||||
base_transaction{raw_tx} {
|
||||
deserialize(raw_tx);
|
||||
}
|
||||
|
||||
const transaction &transaction::sign(const std::string &private_key) const {
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -54,6 +64,20 @@ void transaction::deserialize(const std::string &raw_tx) {
|
|||
|
||||
//! raw_transaction
|
||||
|
||||
raw_transaction::raw_transaction(const std::string &raw_tx) :
|
||||
base_transaction{raw_tx} {
|
||||
deserialize(raw_tx);
|
||||
}
|
||||
|
||||
bytes raw_transaction::hash() const {
|
||||
bytes hash;
|
||||
hash.resize(32);
|
||||
const auto transaction_string = boost::algorithm::unhex(remove_0x(serialize()));
|
||||
keccak_256((const unsigned char *)transaction_string.data(), transaction_string.size(), (unsigned char *)hash.data());
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
signed_transaction raw_transaction::sign(const std::string &private_key) const {
|
||||
//! Prepare signed transaction
|
||||
signed_transaction tr;
|
||||
|
|
@ -64,95 +88,142 @@ signed_transaction raw_transaction::sign(const std::string &private_key) const {
|
|||
tr.value = value;
|
||||
tr.data = data;
|
||||
|
||||
//! Calculate keccak hash of transaction
|
||||
bytes hash;
|
||||
hash.resize(32);
|
||||
const auto transaction_string = boost::algorithm::unhex(remove_0x(serialize()));
|
||||
keccak_256((const unsigned char *)transaction_string.data(), transaction_string.size(), (unsigned char *)hash.data());
|
||||
|
||||
const bytes priv_key = parse_hex(private_key);
|
||||
|
||||
int recid = 0;
|
||||
secp256k1_ecdsa_recoverable_signature sig;
|
||||
FC_ASSERT(secp256k1_ecdsa_sign_recoverable(eth_context(), &sig, (const unsigned char *)hash.data(), (const unsigned char *)priv_key.data(), NULL, NULL));
|
||||
FC_ASSERT(secp256k1_ecdsa_sign_recoverable(eth_context(), &sig, (const unsigned char *)hash().data(), (const unsigned char *)priv_key.data(), NULL, NULL));
|
||||
fc::ecc::compact_signature result;
|
||||
FC_ASSERT(secp256k1_ecdsa_recoverable_signature_serialize_compact(eth_context(), (unsigned char *)result.begin() + 1, &recid, &sig));
|
||||
|
||||
bytes v = bytes{char(recid + from_hex<int>(chain_id) * 2 + 35)};
|
||||
bytes r;
|
||||
for (int i = 1; i < 33; i++)
|
||||
r.emplace_back((char)result.at(i));
|
||||
|
||||
bytes v = bytes{char(recid + from_hex<int>(chain_id) * 2 + 35)};
|
||||
|
||||
bytes s;
|
||||
for (int i = 33; i < 65; i++)
|
||||
s.emplace_back((char)result.at(i));
|
||||
|
||||
tr.v = fc::to_hex((char *)&v[0], v.size());
|
||||
tr.r = fc::to_hex((char *)&r[0], r.size());
|
||||
tr.v = fc::to_hex((char *)&v[0], v.size());
|
||||
tr.s = fc::to_hex((char *)&s[0], s.size());
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
std::string raw_transaction::serialize() const {
|
||||
rlp_encoder encoder;
|
||||
const std::string serialized = encoder.encode(remove_0x(nonce)) +
|
||||
encoder.encode(remove_0x(gas_price)) +
|
||||
encoder.encode(remove_0x(gas_limit)) +
|
||||
encoder.encode(remove_0x(to)) +
|
||||
encoder.encode(remove_0x(value)) +
|
||||
encoder.encode(remove_0x(data)) +
|
||||
encoder.encode(remove_0x(chain_id)) +
|
||||
encoder.encode("") +
|
||||
encoder.encode("");
|
||||
const std::string serialized = rlp_encoder::encode(remove_0x(nonce)) +
|
||||
rlp_encoder::encode(remove_0x(gas_price)) +
|
||||
rlp_encoder::encode(remove_0x(gas_limit)) +
|
||||
rlp_encoder::encode(remove_0x(to)) +
|
||||
rlp_encoder::encode(remove_0x(value)) +
|
||||
rlp_encoder::encode(remove_0x(data)) +
|
||||
rlp_encoder::encode(remove_0x(chain_id)) +
|
||||
rlp_encoder::encode("") +
|
||||
rlp_encoder::encode("");
|
||||
|
||||
return add_0x(bytes2hex(encoder.encode_length(serialized.size(), 192) + serialized));
|
||||
return add_0x(bytes2hex(rlp_encoder::encode_length(serialized.size(), 192) + serialized));
|
||||
}
|
||||
|
||||
void raw_transaction::deserialize(const std::string &raw_tx) {
|
||||
rlp_decoder decoder;
|
||||
const auto rlp_array = decoder.decode(remove_0x(raw_tx));
|
||||
const auto rlp_array = rlp_decoder::decode(remove_0x(raw_tx));
|
||||
FC_ASSERT(rlp_array.size() >= 7, "Wrong rlp format");
|
||||
|
||||
nonce = add_0x(rlp_array.at(0));
|
||||
nonce = !rlp_array.at(0).empty() ? add_0x(rlp_array.at(0)) : add_0x("0");
|
||||
boost::algorithm::to_lower(nonce);
|
||||
gas_price = add_0x(rlp_array.at(1));
|
||||
boost::algorithm::to_lower(gas_price);
|
||||
gas_limit = add_0x(rlp_array.at(2));
|
||||
boost::algorithm::to_lower(gas_limit);
|
||||
to = add_0x(rlp_array.at(3));
|
||||
value = add_0x(rlp_array.at(4));
|
||||
data = add_0x(rlp_array.at(5));
|
||||
boost::algorithm::to_lower(to);
|
||||
value = !rlp_array.at(4).empty() ? add_0x(rlp_array.at(4)) : add_0x("0");
|
||||
boost::algorithm::to_lower(value);
|
||||
data = !rlp_array.at(5).empty() ? add_0x(rlp_array.at(5)) : "";
|
||||
boost::algorithm::to_lower(data);
|
||||
chain_id = add_0x(rlp_array.at(6));
|
||||
boost::algorithm::to_lower(chain_id);
|
||||
}
|
||||
|
||||
//! signed_transaction
|
||||
|
||||
std::string signed_transaction::serialize() const {
|
||||
rlp_encoder encoder;
|
||||
const std::string serialized = encoder.encode(remove_0x(nonce)) +
|
||||
encoder.encode(remove_0x(gas_price)) +
|
||||
encoder.encode(remove_0x(gas_limit)) +
|
||||
encoder.encode(remove_0x(to)) +
|
||||
encoder.encode(remove_0x(value)) +
|
||||
encoder.encode(remove_0x(data)) +
|
||||
encoder.encode(remove_0x(v)) +
|
||||
encoder.encode(remove_0x(r)) +
|
||||
encoder.encode(remove_0x(s));
|
||||
signed_transaction::signed_transaction(const std::string &raw_tx) :
|
||||
base_transaction{raw_tx} {
|
||||
deserialize(raw_tx);
|
||||
}
|
||||
|
||||
return add_0x(bytes2hex(encoder.encode_length(serialized.size(), 192) + serialized));
|
||||
std::string signed_transaction::recover(const std::string &chain_id) const {
|
||||
fc::ecc::compact_signature input64;
|
||||
fc::from_hex(r, (char *)&input64.at(1), 32);
|
||||
fc::from_hex(v, (char *)&input64.at(0), 1);
|
||||
int recid = input64.at(0) - from_hex<int>(chain_id) * 2 - 35;
|
||||
fc::from_hex(s, (char *)&input64.at(33), 32);
|
||||
|
||||
secp256k1_ecdsa_recoverable_signature sig;
|
||||
FC_ASSERT(secp256k1_ecdsa_recoverable_signature_parse_compact(eth_context(), &sig, (const unsigned char *)&input64.data[1], recid));
|
||||
|
||||
raw_transaction tr;
|
||||
tr.nonce = nonce;
|
||||
tr.gas_price = gas_price;
|
||||
tr.gas_limit = gas_limit;
|
||||
tr.to = to;
|
||||
tr.value = value;
|
||||
tr.data = data;
|
||||
tr.chain_id = chain_id;
|
||||
|
||||
secp256k1_pubkey rawPubkey;
|
||||
FC_ASSERT(secp256k1_ecdsa_recover(eth_context(), &rawPubkey, &sig, (const unsigned char *)tr.hash().data()));
|
||||
|
||||
std::array<uint8_t, 65> pubkey;
|
||||
size_t biglen = 65;
|
||||
FC_ASSERT(secp256k1_ec_pubkey_serialize(eth_context(), pubkey.data(), &biglen, &rawPubkey, SECP256K1_EC_UNCOMPRESSED));
|
||||
|
||||
const std::string out = std::string(pubkey.begin(), pubkey.end()).substr(1);
|
||||
bytes hash;
|
||||
hash.resize(32);
|
||||
keccak_256((const unsigned char *)out.data(), out.size(), (unsigned char *)hash.data());
|
||||
|
||||
return add_0x(fc::to_hex((char *)&hash[0], hash.size()).substr(24));
|
||||
}
|
||||
|
||||
std::string signed_transaction::serialize() const {
|
||||
const std::string serialized = rlp_encoder::encode(remove_0x(nonce)) +
|
||||
rlp_encoder::encode(remove_0x(gas_price)) +
|
||||
rlp_encoder::encode(remove_0x(gas_limit)) +
|
||||
rlp_encoder::encode(remove_0x(to)) +
|
||||
rlp_encoder::encode(remove_0x(value)) +
|
||||
rlp_encoder::encode(remove_0x(data)) +
|
||||
rlp_encoder::encode(remove_0x(v)) +
|
||||
rlp_encoder::encode(remove_0x(r)) +
|
||||
rlp_encoder::encode(remove_0x(s));
|
||||
|
||||
return add_0x(bytes2hex(rlp_encoder::encode_length(serialized.size(), 192) + serialized));
|
||||
}
|
||||
|
||||
void signed_transaction::deserialize(const std::string &raw_tx) {
|
||||
rlp_decoder decoder;
|
||||
const auto rlp_array = decoder.decode(remove_0x(raw_tx));
|
||||
const auto rlp_array = rlp_decoder::decode(remove_0x(raw_tx));
|
||||
FC_ASSERT(rlp_array.size() >= 9, "Wrong rlp format");
|
||||
|
||||
nonce = add_0x(rlp_array.at(0));
|
||||
nonce = !rlp_array.at(0).empty() ? add_0x(rlp_array.at(0)) : add_0x("0");
|
||||
boost::algorithm::to_lower(nonce);
|
||||
gas_price = add_0x(rlp_array.at(1));
|
||||
boost::algorithm::to_lower(gas_price);
|
||||
gas_limit = add_0x(rlp_array.at(2));
|
||||
boost::algorithm::to_lower(gas_limit);
|
||||
to = add_0x(rlp_array.at(3));
|
||||
value = add_0x(rlp_array.at(4));
|
||||
data = add_0x(rlp_array.at(5));
|
||||
boost::algorithm::to_lower(to);
|
||||
value = !rlp_array.at(4).empty() ? add_0x(rlp_array.at(4)) : add_0x("0");
|
||||
boost::algorithm::to_lower(value);
|
||||
data = !rlp_array.at(5).empty() ? add_0x(rlp_array.at(5)) : "";
|
||||
boost::algorithm::to_lower(data);
|
||||
v = add_0x(rlp_array.at(6));
|
||||
boost::algorithm::to_lower(v);
|
||||
r = add_0x(rlp_array.at(7));
|
||||
boost::algorithm::to_lower(r);
|
||||
s = add_0x(rlp_array.at(8));
|
||||
boost::algorithm::to_lower(s);
|
||||
}
|
||||
|
||||
}}} // namespace graphene::peerplays_sidechain::ethereum
|
||||
|
|
|
|||
|
|
@ -4,9 +4,15 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <graphene/peerplays_sidechain/ethereum/types.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain { namespace ethereum {
|
||||
|
||||
class base_transaction {
|
||||
public:
|
||||
base_transaction() = default;
|
||||
base_transaction(const std::string &raw_tx);
|
||||
|
||||
virtual std::string serialize() const = 0;
|
||||
virtual void deserialize(const std::string &raw_tx) = 0;
|
||||
};
|
||||
|
|
@ -17,6 +23,9 @@ public:
|
|||
std::string to;
|
||||
std::string data;
|
||||
|
||||
transaction() = default;
|
||||
transaction(const std::string &raw_tx);
|
||||
|
||||
const transaction &sign(const std::string &private_key) const;
|
||||
|
||||
virtual std::string serialize() const override;
|
||||
|
|
@ -34,6 +43,10 @@ public:
|
|||
std::string data;
|
||||
std::string chain_id;
|
||||
|
||||
raw_transaction() = default;
|
||||
raw_transaction(const std::string &raw_tx);
|
||||
|
||||
bytes hash() const;
|
||||
signed_transaction sign(const std::string &private_key) const;
|
||||
|
||||
virtual std::string serialize() const override;
|
||||
|
|
@ -52,6 +65,11 @@ public:
|
|||
std::string r;
|
||||
std::string s;
|
||||
|
||||
signed_transaction() = default;
|
||||
signed_transaction(const std::string &raw_tx);
|
||||
|
||||
std::string recover(const std::string &chain_id) const;
|
||||
|
||||
virtual std::string serialize() const override;
|
||||
virtual void deserialize(const std::string &raw_tx) override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -546,7 +546,7 @@ std::string sidechain_net_handler_ethereum::send_sidechain_transaction(const sid
|
|||
const auto &transaction = signature.second;
|
||||
|
||||
//! Check if we have this signed transaction, if not, don't send it
|
||||
if(transaction.empty())
|
||||
if (transaction.empty())
|
||||
continue;
|
||||
|
||||
#ifdef SEND_RAW_TRANSACTION
|
||||
|
|
@ -625,7 +625,7 @@ std::string sidechain_net_handler_ethereum::create_primary_wallet_transaction(co
|
|||
owners_weights.emplace_back(std::make_pair(pub_key_str, son.weight));
|
||||
}
|
||||
|
||||
ethereum::update_owners_encoder encoder;
|
||||
const ethereum::update_owners_encoder encoder;
|
||||
return encoder.encode(owners_weights, object_id);
|
||||
}
|
||||
|
||||
|
|
@ -634,7 +634,7 @@ std::string sidechain_net_handler_ethereum::create_deposit_transaction(const son
|
|||
}
|
||||
|
||||
std::string sidechain_net_handler_ethereum::create_withdrawal_transaction(const son_wallet_withdraw_object &swwo) {
|
||||
ethereum::withdrawal_encoder encoder;
|
||||
const ethereum::withdrawal_encoder encoder;
|
||||
return encoder.encode(swwo.withdraw_address.substr(2), swwo.withdraw_amount.value * 10000000000, swwo.id.operator std::string());
|
||||
}
|
||||
|
||||
|
|
|
|||
147
tests/peerplays_sidechain/ethereum_transaction_tests.cpp
Normal file
147
tests/peerplays_sidechain/ethereum_transaction_tests.cpp
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <fc/crypto/hex.hpp>
|
||||
#include <graphene/peerplays_sidechain/ethereum/encoders.hpp>
|
||||
#include <graphene/peerplays_sidechain/ethereum/transaction.hpp>
|
||||
|
||||
using namespace graphene::peerplays_sidechain::ethereum;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(ethereum_transaction_tests)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(withdrawal_encoder_test) {
|
||||
const withdrawal_encoder encoder;
|
||||
const auto tx = encoder.encode("5fbbb31be52608d2f52247e8400b7fcaa9e0bc12", 10000000000, "1.36.0");
|
||||
BOOST_CHECK_EQUAL(tx, "0xe088747b0000000000000000000000005fbbb31be52608d2f52247e8400b7fcaa9e0bc1200000000000000000000000000000000000000000000000000000002540be40000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000006312E33362E300000000000000000000000000000000000000000000000000000");
|
||||
|
||||
const auto tx1 = encoder.encode("5fbbb31be52608d2f52247e8400b7fcaa9e0bc12", 10000000000, "1.36.1");
|
||||
BOOST_CHECK_EQUAL(tx1, "0xe088747b0000000000000000000000005fbbb31be52608d2f52247e8400b7fcaa9e0bc1200000000000000000000000000000000000000000000000000000002540be40000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000006312E33362E310000000000000000000000000000000000000000000000000000");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(update_owners_encoder_test) {
|
||||
std::vector<std::pair<std::string, uint16_t>> owners_weights;
|
||||
owners_weights.emplace_back("5FbBb31BE52608D2F52247E8400B7fCaA9E0bC12", 1);
|
||||
owners_weights.emplace_back("76ce31bd03f601c3fc13732def921c5bac282676", 1);
|
||||
|
||||
const update_owners_encoder encoder;
|
||||
const auto tx = encoder.encode(owners_weights, "1.35.0");
|
||||
BOOST_CHECK_EQUAL(tx, "0x23ab6adf000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000005FbBb31BE52608D2F52247E8400B7fCaA9E0bC12000000000000000000000000000000000000000000000000000000000000000100000000000000000000000076ce31bd03f601c3fc13732def921c5bac28267600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000006312E33352E300000000000000000000000000000000000000000000000000000");
|
||||
|
||||
owners_weights.emplace_back("09ee460834498a4ee361beb819470061b7381b49", 1);
|
||||
const auto tx1 = encoder.encode(owners_weights, "1.36.1");
|
||||
BOOST_CHECK_EQUAL(tx1, "0x23ab6adf0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000030000000000000000000000005FbBb31BE52608D2F52247E8400B7fCaA9E0bC12000000000000000000000000000000000000000000000000000000000000000100000000000000000000000076ce31bd03f601c3fc13732def921c5bac282676000000000000000000000000000000000000000000000000000000000000000100000000000000000000000009ee460834498a4ee361beb819470061b7381b4900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000006312E33362E310000000000000000000000000000000000000000000000000000");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(raw_transaction_serialization_test) {
|
||||
raw_transaction raw_tr;
|
||||
raw_tr.nonce = "0x0";
|
||||
raw_tr.gas_price = "0x3b9aca07";
|
||||
raw_tr.gas_limit = "0x7a1200";
|
||||
raw_tr.to = "0x875a7e0eFe5140c80C5c822f99C02281C0290348";
|
||||
raw_tr.value = "";
|
||||
raw_tr.data = "";
|
||||
raw_tr.chain_id = "0x21";
|
||||
|
||||
const auto tx = raw_tr.serialize();
|
||||
BOOST_CHECK_EQUAL(tx, "0xE480843B9ACA07837A120094875A7E0EFE5140C80C5C822F99C02281C02903488080218080");
|
||||
|
||||
//! Change value
|
||||
raw_tr.value = "0x1BC16D674EC80000";
|
||||
const auto tx1 = raw_tr.serialize();
|
||||
BOOST_CHECK_EQUAL(tx1, "0xEC80843B9ACA07837A120094875A7E0EFE5140C80C5C822F99C02281C0290348881BC16D674EC8000080218080");
|
||||
|
||||
//! Change data
|
||||
raw_tr.data = "0x893d20e8";
|
||||
const auto tx2 = raw_tr.serialize();
|
||||
BOOST_CHECK_EQUAL(tx2, "0xF080843B9ACA07837A120094875A7E0EFE5140C80C5C822F99C02281C0290348881BC16D674EC8000084893D20E8218080");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(raw_transaction_deserialization_test) {
|
||||
const raw_transaction raw_tr{"E480843B9ACA07837A120094875A7E0EFE5140C80C5C822F99C02281C02903488080218080"};
|
||||
|
||||
BOOST_CHECK_EQUAL(raw_tr.nonce, "0x0");
|
||||
BOOST_CHECK_EQUAL(raw_tr.gas_price, "0x3b9aca07");
|
||||
BOOST_CHECK_EQUAL(raw_tr.gas_limit, "0x7a1200");
|
||||
BOOST_CHECK_EQUAL(raw_tr.to, "0x875a7e0efe5140c80c5c822f99c02281c0290348");
|
||||
BOOST_CHECK_EQUAL(raw_tr.value, "0x0");
|
||||
BOOST_CHECK_EQUAL(raw_tr.data, "");
|
||||
BOOST_CHECK_EQUAL(raw_tr.chain_id, "0x21");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(raw_transaction_hash_test) {
|
||||
raw_transaction raw_tr;
|
||||
raw_tr.nonce = "0x0";
|
||||
raw_tr.gas_price = "0x3b9aca07";
|
||||
raw_tr.gas_limit = "0x7a1200";
|
||||
raw_tr.to = "0x875a7e0eFe5140c80C5c822f99C02281C0290348";
|
||||
raw_tr.value = "";
|
||||
raw_tr.data = "";
|
||||
raw_tr.chain_id = "0x21";
|
||||
|
||||
const auto tx = raw_tr.serialize();
|
||||
BOOST_CHECK_EQUAL(tx, "0xE480843B9ACA07837A120094875A7E0EFE5140C80C5C822F99C02281C02903488080218080");
|
||||
|
||||
const auto hash = raw_tr.hash();
|
||||
const auto hash_str = fc::to_hex((char *)&hash[0], hash.size());
|
||||
BOOST_CHECK_EQUAL(hash_str, "34934410cd305f4fa4e75a2c9294d625d6fbba729b5642ed2ca757ead50bb1fb");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sign_transaction_test) {
|
||||
raw_transaction raw_tr;
|
||||
raw_tr.nonce = "0x0";
|
||||
raw_tr.gas_price = "0x3b9aca07";
|
||||
raw_tr.gas_limit = "0x7a1200";
|
||||
raw_tr.to = "0x875a7e0eFe5140c80C5c822f99C02281C0290348";
|
||||
raw_tr.value = "";
|
||||
raw_tr.data = "";
|
||||
raw_tr.chain_id = "0x21";
|
||||
|
||||
const auto sign_tr = raw_tr.sign("eb5749a569e6141a3b08249d4a0d84f9ef22c67651ba29adb8eb6fd43fc83060");
|
||||
BOOST_CHECK_EQUAL(sign_tr.r, "5f09de6ac850b2a9e94acd709c12d4e9adbabc6b72281ec0bbe13bca7e57c7ce");
|
||||
BOOST_CHECK_EQUAL(sign_tr.v, "65");
|
||||
BOOST_CHECK_EQUAL(sign_tr.s, "7ca5f26c5b3e25f14a32b18ac9a2a41b7c68efd3b04b118e1b1f4bf1c4e299b0");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sign_transaction_serialization_test) {
|
||||
raw_transaction raw_tr;
|
||||
raw_tr.nonce = "0x0";
|
||||
raw_tr.gas_price = "0x3b9aca07";
|
||||
raw_tr.gas_limit = "0x7a1200";
|
||||
raw_tr.to = "0x875a7e0eFe5140c80C5c822f99C02281C0290348";
|
||||
raw_tr.value = "";
|
||||
raw_tr.data = "";
|
||||
raw_tr.chain_id = "0x21";
|
||||
|
||||
const auto sign_tr = raw_tr.sign("eb5749a569e6141a3b08249d4a0d84f9ef22c67651ba29adb8eb6fd43fc83060");
|
||||
const auto tx = sign_tr.serialize();
|
||||
BOOST_CHECK_EQUAL(tx, "0xF86480843B9ACA07837A120094875A7E0EFE5140C80C5C822F99C02281C0290348808065A05F09DE6AC850B2A9E94ACD709C12D4E9ADBABC6B72281EC0BBE13BCA7E57C7CEA07CA5F26C5B3E25F14A32B18AC9A2A41B7C68EFD3B04B118E1B1F4BF1C4E299B0");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sign_transaction_deserialization_test) {
|
||||
const signed_transaction sign_tr{"0xF86480843B9ACA07837A120094875A7E0EFE5140C80C5C822F99C02281C0290348808065A05F09DE6AC850B2A9E94ACD709C12D4E9ADBABC6B72281EC0BBE13BCA7E57C7CEA07CA5F26C5B3E25F14A32B18AC9A2A41B7C68EFD3B04B118E1B1F4BF1C4E299B0"};
|
||||
|
||||
BOOST_CHECK_EQUAL(sign_tr.nonce, "0x0");
|
||||
BOOST_CHECK_EQUAL(sign_tr.gas_price, "0x3b9aca07");
|
||||
BOOST_CHECK_EQUAL(sign_tr.gas_limit, "0x7a1200");
|
||||
BOOST_CHECK_EQUAL(sign_tr.to, "0x875a7e0efe5140c80c5c822f99c02281c0290348");
|
||||
BOOST_CHECK_EQUAL(sign_tr.value, "0x0");
|
||||
BOOST_CHECK_EQUAL(sign_tr.data, "");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sign_transaction_recover_test) {
|
||||
const std::string chain_id = "0x21";
|
||||
|
||||
raw_transaction raw_tr;
|
||||
raw_tr.nonce = "0x0";
|
||||
raw_tr.gas_price = "0x3b9aca07";
|
||||
raw_tr.gas_limit = "0x7a1200";
|
||||
raw_tr.to = "0x875a7e0eFe5140c80C5c822f99C02281C0290348";
|
||||
raw_tr.value = "";
|
||||
raw_tr.data = "";
|
||||
raw_tr.chain_id = chain_id;
|
||||
|
||||
const auto sign_tr = raw_tr.sign("eb5749a569e6141a3b08249d4a0d84f9ef22c67651ba29adb8eb6fd43fc83060");
|
||||
const auto from = sign_tr.recover(chain_id);
|
||||
BOOST_CHECK_EQUAL(from, "0x5fbbb31be52608d2f52247e8400b7fcaa9e0bc12");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
Loading…
Reference in a new issue