remove hardcodes, implementation build_transaction safe_transaction_encoder
This commit is contained in:
parent
647a5369fc
commit
6e213fcfad
2 changed files with 1139 additions and 1097 deletions
|
|
@ -126,6 +126,13 @@ public:
|
||||||
private:
|
private:
|
||||||
class ethereum_function_call_encoder {
|
class ethereum_function_call_encoder {
|
||||||
public:
|
public:
|
||||||
|
enum operation_t {
|
||||||
|
OPERATION_CALL,
|
||||||
|
OPERATION_DELEGATE_CALL
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr const char*const default_prev_addr = "0000000000000000000000000000000000000001";
|
||||||
|
|
||||||
std::string encode_function_signature(const std::string& function_signature);
|
std::string encode_function_signature(const std::string& function_signature);
|
||||||
std::string encode_address(const std::string& addr);
|
std::string encode_address(const std::string& addr);
|
||||||
std::string encode_uint256(const std::string& value);
|
std::string encode_uint256(const std::string& value);
|
||||||
|
|
@ -133,7 +140,23 @@ private:
|
||||||
std::string encode_bytes(const std::string& values);
|
std::string encode_bytes(const std::string& values);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class safe_transaction_encoder {
|
||||||
|
public:
|
||||||
|
static constexpr const char*const default_safe_tx_gas = "0";
|
||||||
|
static constexpr const char*const default_data_gas = "0";
|
||||||
|
static constexpr const char*const default_gas_price = "0";
|
||||||
|
static constexpr const char*const default_gas_token = "0000000000000000000000000000000000000000";
|
||||||
|
static constexpr const char*const default_refund_receiver = "0000000000000000000000000000000000000000";
|
||||||
|
|
||||||
|
std::string create_safe_address(const std::vector<std::string> owner_addresses, uint32_t threshold);
|
||||||
|
std::string build_transaction(const std::string& safe_account_addr, const std::string& value, const std::string& data, uint8_t operation, const std::string& safeTxGas, const std::string& dataGas, const std::string& gasPrice, const std::string& gasToken, const std::string& refundReceiver);
|
||||||
|
|
||||||
|
private:
|
||||||
ethereum_function_call_encoder m_ethereum_function_call_encoder;
|
ethereum_function_call_encoder m_ethereum_function_call_encoder;
|
||||||
|
};
|
||||||
|
|
||||||
|
ethereum_function_call_encoder m_ethereum_function_call_encoder;
|
||||||
|
safe_transaction_encoder m_safe_transaction_encoder;
|
||||||
|
|
||||||
std::shared_ptr<fc::thread> _thread;
|
std::shared_ptr<fc::thread> _thread;
|
||||||
std::string signature;
|
std::string signature;
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ std::string eth_rpc_client::ethereum_function_call_encoder::encode_function_sign
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_address(const std::string& addr) {
|
std::string eth_rpc_client::ethereum_function_call_encoder::encode_address(const std::string& addr) {
|
||||||
FC_ASSERT(20 == addr.length());
|
FC_ASSERT(40 == addr.length());
|
||||||
std::string output = str(boost::format("%012u") % 0) + addr;
|
std::string output = str(boost::format("%024u") % 0) + addr;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,6 +66,36 @@ std::string eth_rpc_client::ethereum_function_call_encoder::encode_bytes(const s
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string eth_rpc_client::safe_transaction_encoder::create_safe_address(const std::vector<std::string> owner_addresses, uint32_t threshold) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string eth_rpc_client::safe_transaction_encoder::build_transaction(const std::string& safe_account_addr, const std::string& value, const std::string& data, uint8_t operation, const std::string& safeTxGas, const std::string& dataGas, const std::string& gasPrice, const std::string& gasToken, const std::string& refundReceiver){
|
||||||
|
//execTransaction method of smart contract , using safe-account address
|
||||||
|
//execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 dataGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)
|
||||||
|
std::string method_id = m_ethereum_function_call_encoder.encode_function_signature("execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)");
|
||||||
|
FC_ASSERT("6a761202" == method_id);
|
||||||
|
//"<checksummed address>"
|
||||||
|
std::string to = m_ethereum_function_call_encoder.encode_address(safe_account_addr);
|
||||||
|
// Value in wei
|
||||||
|
std::string value_encoded = m_ethereum_function_call_encoder.encode_uint256(value);
|
||||||
|
// 0 CALL, 1 DELEGATE_CALL
|
||||||
|
std::string operation_encoded = m_ethereum_function_call_encoder.encode_uint8(operation);
|
||||||
|
// Max gas to use in the transaction
|
||||||
|
std::string safeTxGas_encoded = m_ethereum_function_call_encoder.encode_uint256(safeTxGas);
|
||||||
|
// Gas costs not related to the transaction execution (signature check, refund payment...)
|
||||||
|
std::string dataGas_encoded = m_ethereum_function_call_encoder.encode_uint256(dataGas);
|
||||||
|
// Gas price used for the refund calculation
|
||||||
|
std::string gasPrice_encoded = m_ethereum_function_call_encoder.encode_uint256(gasPrice);
|
||||||
|
//"<checksummed address>", Token address (hold by the Safe) to be used as a refund to the sender, if `null` is Ether
|
||||||
|
std::string gasToken_encoded = m_ethereum_function_call_encoder.encode_address(gasToken);
|
||||||
|
//"<checksummed address>", Address of receiver of gas payment (or `null` if tx.origin)
|
||||||
|
std::string refundReceiver_encoded = m_ethereum_function_call_encoder.encode_address(refundReceiver);
|
||||||
|
|
||||||
|
std::string message = method_id + to + value_encoded + data + operation_encoded + safeTxGas_encoded + dataGas_encoded + gasPrice_encoded + gasToken_encoded + refundReceiver_encoded;
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
eth_rpc_client::eth_rpc_client(const std::string &url, const std::string &user_name, const std::string &password, bool debug_rpc_calls) : _thread(std::make_shared<fc::thread>("eth_rpc_client")){
|
eth_rpc_client::eth_rpc_client(const std::string &url, const std::string &user_name, const std::string &password, bool debug_rpc_calls) : _thread(std::make_shared<fc::thread>("eth_rpc_client")){
|
||||||
geth_url = url;
|
geth_url = url;
|
||||||
|
|
@ -282,7 +312,10 @@ uint64_t eth_rpc_client::eth_coinbase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t eth_rpc_client::get_list_owners(const std::string& safe_account) {
|
uint64_t eth_rpc_client::get_list_owners(const std::string& safe_account) {
|
||||||
return eth_call(safe_account.c_str(), "0xa0e67e2b");
|
//getOwners()
|
||||||
|
std::string method_id = m_ethereum_function_call_encoder.encode_function_signature("getOwners()");
|
||||||
|
FC_ASSERT("a0e67e2b" == method_id);
|
||||||
|
return eth_call(safe_account.c_str(), method_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t eth_rpc_client::add_owner(const std::string& addr ) {
|
uint64_t eth_rpc_client::add_owner(const std::string& addr ) {
|
||||||
|
|
@ -290,22 +323,14 @@ uint64_t eth_rpc_client::add_owner(const std::string& addr ) {
|
||||||
FC_THROW_EXCEPTION(fc::exception, "Owners allready have addr: ${addr}", ("addr", addr));
|
FC_THROW_EXCEPTION(fc::exception, "Owners allready have addr: ${addr}", ("addr", addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
//It's require to execute
|
|
||||||
//execTransaction method of smart contract , using safe-account address
|
|
||||||
//execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 dataGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)
|
|
||||||
std::string method_id = m_ethereum_function_call_encoder.encode_function_signature("execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)");
|
std::string method_id = m_ethereum_function_call_encoder.encode_function_signature("execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)");
|
||||||
FC_ASSERT("6a761202" == method_id);
|
//addOwnerWithThreshold(address,uint256)
|
||||||
std::string address = safe_account_addr;
|
std::string data_method_id = m_ethereum_function_call_encoder.encode_function_signature("addOwnerWithThreshold(address,uint256)");
|
||||||
std::string value = str(boost::format("%020u") % 0);
|
FC_ASSERT("0d582f13" == data_method_id);
|
||||||
std::string data = "f8dc5dd9000000000000000000000000" + owners[0] + "000000000000000000000000" + addr + str(boost::format("%032u") % threshold);
|
std::string data = data_method_id + m_ethereum_function_call_encoder.encode_address(addr) + m_ethereum_function_call_encoder.encode_uint256((boost::format("%x") % threshold).str());
|
||||||
std::string operation = "0";
|
|
||||||
std::string safeTxGas = str(boost::format("%032u") % 0);
|
std::string message = m_safe_transaction_encoder.build_transaction(safe_account_addr, "0", data, ethereum_function_call_encoder::operation_t::OPERATION_CALL, m_safe_transaction_encoder.default_safe_tx_gas, m_safe_transaction_encoder.default_data_gas, m_safe_transaction_encoder.default_gas_price, m_safe_transaction_encoder.default_gas_token, m_safe_transaction_encoder.default_refund_receiver);
|
||||||
std::string dataGas = str(boost::format("%032u") % 0);
|
|
||||||
std::string gasPrice = str(boost::format("%032u") % 0);
|
|
||||||
std::string gasToken = "0000000000000000000000000000000000000000";
|
|
||||||
std::string refundReceiver = "0000000000000000000000000000000000000000";
|
|
||||||
|
|
||||||
std::string message = method_id + address + value + data + operation + safeTxGas + dataGas + gasPrice + gasToken + refundReceiver;
|
|
||||||
uint64_t id = eth_sign(account_address, message);
|
uint64_t id = eth_sign(account_address, message);
|
||||||
|
|
||||||
m_requests[t_id] = req_t::ADD_OWNER;
|
m_requests[t_id] = req_t::ADD_OWNER;
|
||||||
|
|
@ -322,20 +347,14 @@ uint64_t eth_rpc_client::remove_owner(const std::string& addr, uint32_t threshol
|
||||||
FC_THROW_EXCEPTION(fc::exception, "Owners size does not meet threshold: ${th}", ("th", threshold));
|
FC_THROW_EXCEPTION(fc::exception, "Owners size does not meet threshold: ${th}", ("th", threshold));
|
||||||
}
|
}
|
||||||
|
|
||||||
//It's require to execute
|
//removeOwner(address,address,uint256)
|
||||||
//execTransaction method of smart contract , using safe-account address
|
std::string data_method_id = m_ethereum_function_call_encoder.encode_function_signature("removeOwner(address,address,uint256)");
|
||||||
//execTransaction(address to, uint256 value, bytes data, uint8 operation, uint256 safeTxGas, uint256 dataGas, uint256 gasPrice, address gasToken, address refundReceiver, bytes signatures)
|
FC_ASSERT("f8dc5dd9" == data_method_id);
|
||||||
std::string method_id = m_ethereum_function_call_encoder.encode_function_signature("execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)");
|
std::string data = data_method_id + m_ethereum_function_call_encoder.encode_address(m_ethereum_function_call_encoder.default_prev_addr) + m_ethereum_function_call_encoder.encode_address(addr) + m_ethereum_function_call_encoder.encode_uint256((boost::format("%x") % threshold).str());
|
||||||
FC_ASSERT("6a761202" == method_id);
|
|
||||||
std::string address = safe_account_addr;
|
std::string message = m_safe_transaction_encoder.build_transaction(safe_account_addr, "0", data, ethereum_function_call_encoder::operation_t::OPERATION_CALL, m_safe_transaction_encoder.default_safe_tx_gas, m_safe_transaction_encoder.default_data_gas, m_safe_transaction_encoder.default_gas_price, m_safe_transaction_encoder.default_gas_token, m_safe_transaction_encoder.default_refund_receiver);
|
||||||
std::string value = str(boost::format("%032u") % 0);
|
|
||||||
std::string data = "f8dc5dd90000000000000000000000000000000000000000000000000000000000000001000000000000000000000000" + addr + str(boost::format("%032u") % threshold);
|
uint64_t id = eth_sign(account_address, message);
|
||||||
std::string operatio = "0";
|
|
||||||
std::string safeTxGas = str(boost::format("%032u") % 0);
|
|
||||||
std::string dataGas = str(boost::format("%032u") % 0);
|
|
||||||
std::string gasPrice = str(boost::format("%032u") % 0);
|
|
||||||
std::string gasToken = "0000000000000000000000000000000000000000";
|
|
||||||
std::string refundReceiver = "0000000000000000000000000000000000000000";
|
|
||||||
|
|
||||||
m_requests[t_id] = req_t::REMOVE_OWNER;
|
m_requests[t_id] = req_t::REMOVE_OWNER;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue