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
|
|
@ -21,19 +21,19 @@
|
|||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
||||
typedef websocketpp::client<websocketpp::config::asio_client> client;
|
||||
typedef websocketpp::client<websocketpp::config::asio_client> client;
|
||||
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::placeholders::_2;
|
||||
using websocketpp::lib::bind;
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::placeholders::_2;
|
||||
using websocketpp::lib::bind;
|
||||
|
||||
// pull out the type of messages sent by our config
|
||||
typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr;
|
||||
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
||||
typedef client::connection_ptr connection_ptr;
|
||||
// pull out the type of messages sent by our config
|
||||
typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr;
|
||||
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
||||
typedef client::connection_ptr connection_ptr;
|
||||
|
||||
class eth_rpc_client {
|
||||
public:
|
||||
class eth_rpc_client {
|
||||
public:
|
||||
typedef eth_rpc_client type;
|
||||
|
||||
enum req_t {
|
||||
|
|
@ -123,9 +123,16 @@ public:
|
|||
std::string chain_id;//256 bit value
|
||||
std::vector<std::string> owners;
|
||||
std::string safe_account_addr;
|
||||
private:
|
||||
private:
|
||||
class ethereum_function_call_encoder {
|
||||
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_address(const std::string& addr);
|
||||
std::string encode_uint256(const std::string& value);
|
||||
|
|
@ -133,7 +140,23 @@ private:
|
|||
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;
|
||||
safe_transaction_encoder m_safe_transaction_encoder;
|
||||
|
||||
std::shared_ptr<fc::thread> _thread;
|
||||
std::string signature;
|
||||
|
|
@ -158,12 +181,12 @@ private:
|
|||
|
||||
client m_endpoint;
|
||||
websocketpp::connection_hdl m_hdl;
|
||||
};
|
||||
};
|
||||
|
||||
// =============================================================================
|
||||
// =============================================================================
|
||||
|
||||
class sidechain_net_handler_eth : public sidechain_net_handler {
|
||||
public:
|
||||
class sidechain_net_handler_eth : public sidechain_net_handler {
|
||||
public:
|
||||
sidechain_net_handler_eth(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
||||
virtual ~sidechain_net_handler_eth();
|
||||
|
||||
|
|
@ -176,7 +199,7 @@ public:
|
|||
std::string send_sidechain_transaction(const sidechain_transaction_object &sto);
|
||||
bool settle_sidechain_transaction(const sidechain_transaction_object &sto, asset &settle_amount);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string url;
|
||||
uint32_t rpc_port;
|
||||
|
||||
|
|
@ -209,6 +232,6 @@ private:
|
|||
|
||||
std::vector<char> parse_hex(const std::string &str);
|
||||
fc::ecc::public_key_data create_public_key_data(const std::vector<char> &public_key);
|
||||
};
|
||||
};
|
||||
|
||||
}} // namespace graphene::peerplays_sidechain
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ extern "C" {
|
|||
}
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
// =============================================================================
|
||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_function_signature(const std::string& function_signature) {
|
||||
// =============================================================================
|
||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_function_signature(const std::string& function_signature) {
|
||||
sha3_context c;
|
||||
char *hash;
|
||||
|
||||
|
|
@ -41,33 +41,63 @@ std::string eth_rpc_client::ethereum_function_call_encoder::encode_function_sign
|
|||
output = output.substr(0,8);
|
||||
|
||||
return output;
|
||||
};
|
||||
};
|
||||
|
||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_address(const std::string& addr) {
|
||||
FC_ASSERT(20 == addr.length());
|
||||
std::string output = str(boost::format("%012u") % 0) + addr;
|
||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_address(const std::string& addr) {
|
||||
FC_ASSERT(40 == addr.length());
|
||||
std::string output = str(boost::format("%024u") % 0) + addr;
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_uint256(const std::string& value) {
|
||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_uint256(const std::string& value) {
|
||||
FC_ASSERT(value.length() <= 64);
|
||||
std::string output = std::string(64 - value.length(), '0') + value;
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_uint8(uint8_t value) {
|
||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_uint8(uint8_t value) {
|
||||
std::string output = str(boost::format("%02X") % value) + std::string(62, '0');
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_bytes(const std::string& values) {
|
||||
std::string eth_rpc_client::ethereum_function_call_encoder::encode_bytes(const std::string& values) {
|
||||
size_t len = values.length();
|
||||
std::string output = encode_uint256((boost::format("%x") % len).str()) + values + std::string(64 - len, '0');
|
||||
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;
|
||||
user = user_name;
|
||||
this->password = password;
|
||||
|
|
@ -89,9 +119,9 @@ eth_rpc_client::eth_rpc_client(const std::string &url, const std::string &user_n
|
|||
m_endpoint.set_open_handler(bind(&type::on_open,this,::_1));
|
||||
m_endpoint.set_close_handler(bind(&type::on_close,this,::_1));
|
||||
m_endpoint.set_fail_handler(bind(&type::on_fail,this,::_1));
|
||||
}
|
||||
}
|
||||
|
||||
void eth_rpc_client::start() {
|
||||
void eth_rpc_client::start() {
|
||||
ilog("### eth_rpc_client::start uri: ${uri}", ("uri", geth_url));
|
||||
auto future = _thread->async([this]
|
||||
{
|
||||
|
|
@ -109,16 +139,16 @@ void eth_rpc_client::start() {
|
|||
// Start the ASIO io_service run loop
|
||||
m_endpoint.run();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void eth_rpc_client::stop() {
|
||||
void eth_rpc_client::stop() {
|
||||
m_endpoint.close(m_hdl,websocketpp::close::status::normal,"");
|
||||
}
|
||||
}
|
||||
|
||||
void eth_rpc_client::on_socket_init(websocketpp::connection_hdl) {
|
||||
}
|
||||
void eth_rpc_client::on_socket_init(websocketpp::connection_hdl) {
|
||||
}
|
||||
|
||||
void eth_rpc_client::on_fail(websocketpp::connection_hdl hdl) {
|
||||
void eth_rpc_client::on_fail(websocketpp::connection_hdl hdl) {
|
||||
client::connection_ptr con = m_endpoint.get_con_from_hdl(hdl);
|
||||
|
||||
elog("Ethereum websocket fail");
|
||||
|
|
@ -128,9 +158,9 @@ void eth_rpc_client::on_fail(websocketpp::connection_hdl hdl) {
|
|||
elog("get_remote_close_code: ${close}", ("close", con->get_remote_close_code()));
|
||||
elog("get_remote_close_reason: ${close}", ("close", con->get_remote_close_reason()));
|
||||
elog("get_ec().message(): ${ec}", ("ec", con->get_ec().message()));
|
||||
}
|
||||
}
|
||||
|
||||
void eth_rpc_client::on_open(websocketpp::connection_hdl hdl) {
|
||||
void eth_rpc_client::on_open(websocketpp::connection_hdl hdl) {
|
||||
std::string str = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_chainId\",\"params\":[],\"id\":84}";
|
||||
ilog("on_open: ${str}", ("str", str));
|
||||
m_endpoint.send(hdl, str.c_str(), websocketpp::frame::opcode::text);
|
||||
|
|
@ -138,9 +168,9 @@ void eth_rpc_client::on_open(websocketpp::connection_hdl hdl) {
|
|||
vector<std::string> owner_addresses;
|
||||
std::string private_key = "";
|
||||
createmultisig(5, owner_addresses, private_key);
|
||||
}
|
||||
}
|
||||
|
||||
void eth_rpc_client::on_message(websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
void eth_rpc_client::on_message(websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
|
||||
ilog("on_message: ${msg}", ("msg", msg->get_payload()));
|
||||
|
||||
|
|
@ -199,121 +229,116 @@ void eth_rpc_client::on_message(websocketpp::connection_hdl hdl, message_ptr msg
|
|||
case REMOVE_OWNER:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void eth_rpc_client::on_close(websocketpp::connection_hdl) {
|
||||
void eth_rpc_client::on_close(websocketpp::connection_hdl) {
|
||||
ilog("Ethereum websocket close");
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::get_chain_id() {
|
||||
uint64_t eth_rpc_client::get_chain_id() {
|
||||
std::string req = str(boost::format("{\"jsonrpc\":\"2.0\",\"method\":\"eth_chainId\",\"params\":[],\"id\":%1%}") % t_id);
|
||||
ilog("get_chain_id: ${req}", ("req", req.c_str()));
|
||||
m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text);
|
||||
m_requests[t_id] = req_t::ETH_CHAIN_ID;
|
||||
return t_id++;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::eth_getTransactionReceipt(const std::string& tx_id) {
|
||||
uint64_t eth_rpc_client::eth_getTransactionReceipt(const std::string& tx_id) {
|
||||
std::string req = str(boost::format("{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionReceipt\",\"params\":[\"%1%\"],\"id\":%2%}") % tx_id.c_str() % t_id);
|
||||
ilog("eth_getTransactionReceipt: ${req}", ("req", req.c_str()));
|
||||
m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text);
|
||||
m_requests[t_id] = req_t::ETH_GET_TRANSACTION_RECEIPT;
|
||||
return t_id++;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::eth_call(const std::string& to, const std::string& data) {
|
||||
uint64_t eth_rpc_client::eth_call(const std::string& to, const std::string& data) {
|
||||
std::string req = str(boost::format("{\"jsonrpc\": \"2.0\", \"method\": \"eth_call\", \"params\": [{\"to\": \"%1%\", \"data\": \"%2%\"}, \"latest\"], \"id\": %3%}") % to.c_str() % data.c_str() % t_id);
|
||||
ilog("eth_call: ${req}", ("req", req.c_str()));
|
||||
m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text);
|
||||
m_requests[t_id] = req_t::ETH_CALL;
|
||||
|
||||
return t_id++;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::eth_sendTransaction(const std::string& from, const std::string& to, const std::string& data) {
|
||||
uint64_t eth_rpc_client::eth_sendTransaction(const std::string& from, const std::string& to, const std::string& data) {
|
||||
std::string req = str(boost::format("{\"jsonrpc\":\"2.0\",\"method\": \"eth_sendTransaction\", \"params\": [{\"from\": \"%1%\", \"to\": \"%2%\", \"data\": \"%3%\"}], \"id\": %4%}") % from.c_str() % to.c_str() % data.c_str() % t_id);
|
||||
ilog("eth_sendTransaction: ${req}", ("req", req.c_str()));
|
||||
m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text);
|
||||
m_requests[t_id] = req_t::ETH_SEND_TRANSACTION;
|
||||
|
||||
return t_id++;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::eth_sendRawTransaction(const std::string& params) {
|
||||
uint64_t eth_rpc_client::eth_sendRawTransaction(const std::string& params) {
|
||||
std::string req = str(boost::format("{\"jsonrpc\":\"2.0\",\"method\":\"eth_sendRawTransaction\",\"params\":[\"%1%\"],\"id\":%2%}") % params.c_str() % t_id);
|
||||
ilog("eth_sendRawTransaction: ${req}", ("req", req.c_str()));
|
||||
m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text);
|
||||
m_requests[t_id] = req_t::ETH_SEND_RAW_TRANSACTION;
|
||||
|
||||
return t_id++;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::eth_getCode(const std::string& addr) {
|
||||
uint64_t eth_rpc_client::eth_getCode(const std::string& addr) {
|
||||
std::string req = str(boost::format("{\"jsonrpc\":\"2.0\",\"method\": \"eth_getCode\", \"params\": [\"%1%\",\"latest\"], \"id\": %2%}") % addr.c_str() % t_id);
|
||||
ilog("eth_getCode: ${req}", ("req", req.c_str()));
|
||||
m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text);
|
||||
m_requests[t_id] = req_t::ETH_GET_CODE;
|
||||
return t_id++;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::eth_getBalance(const std::string& addr) {
|
||||
uint64_t eth_rpc_client::eth_getBalance(const std::string& addr) {
|
||||
std::string req = str(boost::format("{\"jsonrpc\":\"2.0\",\"method\": \"eth_getBalance\", \"params\": [\"%1%\",\"latest\"], \"id\": %2%}") % addr.c_str() % t_id);
|
||||
ilog("eth_getBalance: ${req}", ("req", req.c_str()));
|
||||
m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text);
|
||||
m_requests[t_id] = req_t::ETH_GET_BALANCE;
|
||||
return t_id++;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::eth_sign(const string& addr, const string& message) {
|
||||
uint64_t eth_rpc_client::eth_sign(const string& addr, const string& message) {
|
||||
std::string req = str(boost::format("{\"jsonrpc\":\"2.0\",\"method\": \"eth_sign\", \"params\": [\"%1%\",\"%2%\"], \"id\": %2%}") % addr.c_str() % message.c_str() % t_id);
|
||||
ilog("eth_sign: ${req}", ("req", req.c_str()));
|
||||
m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text);
|
||||
m_requests[t_id] = req_t::ETH_SIGN;
|
||||
|
||||
return t_id++;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::eth_coinbase() {
|
||||
uint64_t eth_rpc_client::eth_coinbase() {
|
||||
std::string req = str(boost::format("{\"jsonrpc\":\"2.0\",\"method\":\"eth_coinbase\",\"params\":[],\"id\":%1%}") % t_id);
|
||||
ilog("eth_coinbase: ${req}", ("req", req.c_str()));
|
||||
m_endpoint.send(m_hdl, req.c_str(), websocketpp::frame::opcode::text);
|
||||
m_requests[t_id] = req_t::ETH_COINBASE;
|
||||
return t_id++;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::get_list_owners(const std::string& safe_account) {
|
||||
return eth_call(safe_account.c_str(), "0xa0e67e2b");
|
||||
}
|
||||
uint64_t eth_rpc_client::get_list_owners(const std::string& safe_account) {
|
||||
//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 ) {
|
||||
if (std::count(owners.begin(), owners.end(), 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)");
|
||||
FC_ASSERT("6a761202" == method_id);
|
||||
std::string address = safe_account_addr;
|
||||
std::string value = str(boost::format("%020u") % 0);
|
||||
std::string data = "f8dc5dd9000000000000000000000000" + owners[0] + "000000000000000000000000" + addr + str(boost::format("%032u") % threshold);
|
||||
std::string operation = "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";
|
||||
//addOwnerWithThreshold(address,uint256)
|
||||
std::string data_method_id = m_ethereum_function_call_encoder.encode_function_signature("addOwnerWithThreshold(address,uint256)");
|
||||
FC_ASSERT("0d582f13" == data_method_id);
|
||||
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 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 message = method_id + address + value + data + operation + safeTxGas + dataGas + gasPrice + gasToken + refundReceiver;
|
||||
uint64_t id = eth_sign(account_address, message);
|
||||
|
||||
m_requests[t_id] = req_t::ADD_OWNER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::remove_owner(const std::string& addr, uint32_t threshold) {
|
||||
uint64_t eth_rpc_client::remove_owner(const std::string& addr, uint32_t threshold) {
|
||||
if (!std::count(owners.begin(), owners.end(), addr)){
|
||||
FC_THROW_EXCEPTION(fc::exception, "Owners does not have addr: ${addr}", ("addr", addr));
|
||||
}
|
||||
|
|
@ -322,147 +347,141 @@ 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));
|
||||
}
|
||||
|
||||
//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)");
|
||||
FC_ASSERT("6a761202" == method_id);
|
||||
std::string address = safe_account_addr;
|
||||
std::string value = str(boost::format("%032u") % 0);
|
||||
std::string data = "f8dc5dd90000000000000000000000000000000000000000000000000000000000000001000000000000000000000000" + addr + str(boost::format("%032u") % threshold);
|
||||
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";
|
||||
//removeOwner(address,address,uint256)
|
||||
std::string data_method_id = m_ethereum_function_call_encoder.encode_function_signature("removeOwner(address,address,uint256)");
|
||||
FC_ASSERT("f8dc5dd9" == data_method_id);
|
||||
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());
|
||||
|
||||
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);
|
||||
|
||||
uint64_t id = eth_sign(account_address, message);
|
||||
|
||||
m_requests[t_id] = req_t::REMOVE_OWNER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::addmultisigaddress(const uint32_t nrequired, const std::vector<std::string> public_keys) {
|
||||
std::string eth_rpc_client::addmultisigaddress(const uint32_t nrequired, const std::vector<std::string> public_keys) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::combinepsbt(const vector<std::string> &psbts) {
|
||||
std::string eth_rpc_client::combinepsbt(const vector<std::string> &psbts) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::createmultisig(const uint32_t nrequired, const std::vector<std::string> owner_addresses, const std::string &private_key) {
|
||||
uint64_t eth_rpc_client::createmultisig(const uint32_t nrequired, const std::vector<std::string> owner_addresses, const std::string &private_key) {
|
||||
ilog("createmultisig: ${key}", ("key", private_key.c_str()));
|
||||
|
||||
//That's will create
|
||||
//0x5FbBb31BE52608D2F52247E8400B7fCaA9E0bC12
|
||||
//0x76ce31BD03f601c3fC13732deF921c5Bac282676
|
||||
//0x09EE460834498a4ee361beB819470061B7381B49
|
||||
//0x6AEFbd09209e1eE2e0a589d31e732F69B77713D2
|
||||
//0x631e128b16f9aDCF1bB6385112B1519C917D77a7
|
||||
//0xcD5C788e84220E8b8934Ea4F1dC6a12009bCc91D
|
||||
//0x3627C1B31525887CB9441130C831e35887650305
|
||||
//0x03A13a989AF30C92AD7ABD1E6210308A6c96f373
|
||||
//That's will create
|
||||
//0x5FbBb31BE52608D2F52247E8400B7fCaA9E0bC12
|
||||
//0x76ce31BD03f601c3fC13732deF921c5Bac282676
|
||||
//0x09EE460834498a4ee361beB819470061B7381B49
|
||||
//0x6AEFbd09209e1eE2e0a589d31e732F69B77713D2
|
||||
//0x631e128b16f9aDCF1bB6385112B1519C917D77a7
|
||||
//0xcD5C788e84220E8b8934Ea4F1dC6a12009bCc91D
|
||||
//0x3627C1B31525887CB9441130C831e35887650305
|
||||
//0x03A13a989AF30C92AD7ABD1E6210308A6c96f373
|
||||
|
||||
|
||||
std::string from = "0xeE52b70e8D7AB5Fe661311D47e81228EAD6B06B9";
|
||||
std::string to = "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2";
|
||||
std::string data = "0x1688f0b9000000000000000000000000d9db270c1b5e3bd161e8c8503c55ceabee70955200000000000000000000000000000000000000000000000000000000000000604fa262bd05cdef2e3d5261787ee66d9447a4036324990e04380339bec83b4c7a0000000000000000000000000000000000000000000000000000000000000264b63e800d0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000f48f2b2d2a534e402487b3ee7c18c33aec0fe5e400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000005FbBb31BE52608D2F52247E8400B7fCaA9E0bC1200000000000000000000000076ce31BD03f601c3fC13732deF921c5Bac28267600000000000000000000000009EE460834498a4ee361beB819470061B7381B490000000000000000000000006AEFbd09209e1eE2e0a589d31e732F69B77713D2000000000000000000000000631e128b16f9aDCF1bB6385112B1519C917D77a7000000000000000000000000cD5C788e84220E8b8934Ea4F1dC6a12009bCc91D0000000000000000000000003627C1B31525887CB9441130C831e3588765030500000000000000000000000003A13a989AF30C92AD7ABD1E6210308A6c96f3730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
|
||||
return eth_sendTransaction(from, to, data);
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::createpsbt() {
|
||||
}
|
||||
std::string eth_rpc_client::createpsbt() {
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::createrawtransaction() {
|
||||
std::string eth_rpc_client::createrawtransaction() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::createwallet(const std::string &wallet_name) {
|
||||
std::string eth_rpc_client::createwallet(const std::string &wallet_name) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::decodepsbt(std::string const &tx_psbt) {
|
||||
std::string eth_rpc_client::decodepsbt(std::string const &tx_psbt) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::decoderawtransaction(std::string const &tx_hex) {
|
||||
std::string eth_rpc_client::decoderawtransaction(std::string const &tx_hex) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::encryptwallet(const std::string &passphrase) {
|
||||
std::string eth_rpc_client::encryptwallet(const std::string &passphrase) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t eth_rpc_client::estimatesmartfee(uint16_t conf_target) {
|
||||
uint64_t eth_rpc_client::estimatesmartfee(uint16_t conf_target) {
|
||||
return 20000;
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::finalizepsbt(std::string const &tx_psbt) {
|
||||
std::string eth_rpc_client::finalizepsbt(std::string const &tx_psbt) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::getaddressinfo(const std::string &address) {
|
||||
std::string eth_rpc_client::getaddressinfo(const std::string &address) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::getblock(const std::string &block_hash, int32_t verbosity) {
|
||||
std::string eth_rpc_client::getblock(const std::string &block_hash, int32_t verbosity) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::getnetworkinfo() {
|
||||
std::string eth_rpc_client::getnetworkinfo() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::getrawtransaction(const std::string &txid, const bool verbose) {
|
||||
std::string eth_rpc_client::getrawtransaction(const std::string &txid, const bool verbose) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::gettransaction(const std::string &txid, const bool include_watch_only) {
|
||||
std::string eth_rpc_client::gettransaction(const std::string &txid, const bool include_watch_only) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::getblockchaininfo() {
|
||||
std::string eth_rpc_client::getblockchaininfo() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void eth_rpc_client::importaddress(const std::string &address_or_script, const std::string &label, const bool rescan, const bool p2sh) {
|
||||
void eth_rpc_client::importaddress(const std::string &address_or_script, const std::string &label, const bool rescan, const bool p2sh) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void eth_rpc_client::importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan) {
|
||||
}
|
||||
void eth_rpc_client::importmulti(const std::vector<multi_params> &address_or_script_array, const bool rescan) {
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::loadwallet(const std::string &filename) {
|
||||
std::string eth_rpc_client::loadwallet(const std::string &filename) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::sendrawtransaction(const std::string &tx_hex) {
|
||||
std::string eth_rpc_client::sendrawtransaction(const std::string &tx_hex) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::signrawtransactionwithwallet(const std::string &tx_hash) {
|
||||
std::string eth_rpc_client::signrawtransactionwithwallet(const std::string &tx_hash) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::unloadwallet(const std::string &filename) {
|
||||
std::string eth_rpc_client::unloadwallet(const std::string &filename) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::walletlock() {
|
||||
std::string eth_rpc_client::walletlock() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string eth_rpc_client::walletprocesspsbt(std::string const &tx_psbt) {
|
||||
std::string eth_rpc_client::walletprocesspsbt(std::string const &tx_psbt) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
bool eth_rpc_client::walletpassphrase(const std::string &passphrase, uint32_t timeout) {
|
||||
bool eth_rpc_client::walletpassphrase(const std::string &passphrase, uint32_t timeout) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// =============================================================================
|
||||
|
||||
sidechain_net_handler_eth::sidechain_net_handler_eth(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
||||
sidechain_net_handler_eth::sidechain_net_handler_eth(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
||||
sidechain_net_handler(_plugin, options) {
|
||||
sidechain = sidechain_type::ethereum;
|
||||
|
||||
|
|
@ -473,7 +492,7 @@ sidechain_net_handler_eth::sidechain_net_handler_eth(peerplays_sidechain_plugin
|
|||
url = options.at("ethereum-node-rpc-url").as<std::string>();
|
||||
eth_client = std::unique_ptr<eth_rpc_client>(new eth_rpc_client(url, rpc_user, rpc_password, debug_rpc_calls));
|
||||
eth_client->start();
|
||||
/*
|
||||
/*
|
||||
if (!wallet.empty()) {
|
||||
eth_client->loadwallet(wallet);
|
||||
}
|
||||
|
|
@ -485,7 +504,7 @@ sidechain_net_handler_eth::sidechain_net_handler_eth(peerplays_sidechain_plugin
|
|||
database.changed_objects.connect([this](const vector<object_id_type> &ids, const flat_set<account_id_type> &accounts) {
|
||||
on_changed_objects(ids, accounts);
|
||||
});
|
||||
*/
|
||||
*/
|
||||
}
|
||||
|
||||
sidechain_net_handler_eth::~sidechain_net_handler_eth() {
|
||||
|
|
@ -503,7 +522,7 @@ sidechain_net_handler_eth::~sidechain_net_handler_eth() {
|
|||
bool sidechain_net_handler_eth::process_proposal(const proposal_object &po) {
|
||||
|
||||
ilog("Proposal to process: ${po}, SON id ${son_id}", ("po", po.id)("son_id", plugin.get_current_son_id()));
|
||||
/*
|
||||
/*
|
||||
bool should_approve = false;
|
||||
|
||||
const chain::global_property_object &gpo = database.get_global_properties();
|
||||
|
|
@ -588,17 +607,17 @@ bool sidechain_net_handler_eth::process_proposal(const proposal_object &po) {
|
|||
|
||||
transaction_ok = (op_tx_str == tx_str);
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
transaction_ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
should_approve = address_ok &&
|
||||
transaction_ok;
|
||||
break;
|
||||
}
|
||||
should_approve = address_ok &&
|
||||
transaction_ok;
|
||||
break;
|
||||
}
|
||||
|
||||
case chain::operation::tag<chain::son_wallet_deposit_process_operation>::value: {
|
||||
case chain::operation::tag<chain::son_wallet_deposit_process_operation>::value: {
|
||||
bool process_ok = false;
|
||||
bool transaction_ok = false;
|
||||
son_wallet_deposit_id_type swdo_id = op_obj_idx_0.get<son_wallet_deposit_process_operation>().son_wallet_deposit_id;
|
||||
|
|
@ -681,7 +700,7 @@ bool sidechain_net_handler_eth::process_proposal(const proposal_object &po) {
|
|||
break;
|
||||
}
|
||||
|
||||
case chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value: {
|
||||
case chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value: {
|
||||
bool process_ok = false;
|
||||
bool transaction_ok = false;
|
||||
son_wallet_withdraw_id_type swwo_id = op_obj_idx_0.get<son_wallet_withdraw_process_operation>().son_wallet_withdraw_id;
|
||||
|
|
@ -736,7 +755,7 @@ bool sidechain_net_handler_eth::process_proposal(const proposal_object &po) {
|
|||
break;
|
||||
}
|
||||
|
||||
case chain::operation::tag<chain::sidechain_transaction_sign_operation>::value: {
|
||||
case chain::operation::tag<chain::sidechain_transaction_sign_operation>::value: {
|
||||
using namespace bitcoin;
|
||||
should_approve = true;
|
||||
son_id_type signer = op_obj_idx_0.get<sidechain_transaction_sign_operation>().signer;
|
||||
|
|
@ -771,22 +790,22 @@ bool sidechain_net_handler_eth::process_proposal(const proposal_object &po) {
|
|||
break;
|
||||
}
|
||||
|
||||
case chain::operation::tag<chain::sidechain_transaction_settle_operation>::value: {
|
||||
case chain::operation::tag<chain::sidechain_transaction_settle_operation>::value: {
|
||||
should_approve = true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
should_approve = false;
|
||||
elog("==================================================");
|
||||
elog("Proposal not considered for approval ${po}", ("po", po));
|
||||
elog("==================================================");
|
||||
}
|
||||
default:
|
||||
should_approve = false;
|
||||
elog("==================================================");
|
||||
elog("Proposal not considered for approval ${po}", ("po", po));
|
||||
elog("==================================================");
|
||||
}
|
||||
|
||||
return should_approve;
|
||||
*/
|
||||
return should_approve;
|
||||
*/
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void sidechain_net_handler_eth::process_primary_wallet() {
|
||||
|
|
@ -867,7 +886,7 @@ void sidechain_net_handler_eth::process_primary_wallet() {
|
|||
}
|
||||
|
||||
void sidechain_net_handler_eth::process_sidechain_addresses() {
|
||||
/*
|
||||
/*
|
||||
const chain::global_property_object &gpo = database.get_global_properties();
|
||||
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkeys;
|
||||
for (auto &son : gpo.active_sons) {
|
||||
|
|
@ -920,7 +939,7 @@ void sidechain_net_handler_eth::process_sidechain_addresses() {
|
|||
}
|
||||
return retval;
|
||||
});
|
||||
*/
|
||||
*/
|
||||
}
|
||||
|
||||
bool sidechain_net_handler_eth::process_deposit(const son_wallet_deposit_object &swdo) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue