在作一個EOS 的action接口時,定義以下:ui
void setbplist(const account_name bp_name, const uint64_t bp_time, const std::string hash_bplist, const std::vector< uosio::producer_key >& bplist);
其中有一個結構uosio::producer_key,它在合約的結構中是以下定義:編碼
struct /* */producer_key { account_name producer_name; public_key block_signing_key; friend bool operator < ( const producer_key& a, const producer_key& b ) { return a.producer_name < b.producer_name; } UOSLIB_SERIALIZE( producer_key, (producer_name)(block_signing_key)) };
其中 public_key 定義以下:spa
struct public_key { unsigned_int type; std::array<char,33> data; friend bool operator == ( const public_key& a, const public_key& b ) { return std::tie(a.type,a.data) == std::tie(b.type,b.data); } friend bool operator != ( const public_key& a, const public_key& b ) { return std::tie(a.type,a.data) != std::tie(b.type,b.data); } UOSLIB_SERIALIZE( public_key, (type)(data) ) };
這裏的 public_key 是一個壓縮成33個字節的數據,但其實我傳的是 一組公匙,我想在智能合約裏還原成公匙的形態。EOS公匙是基於base58編碼,這個與比特幣的一致,這裏再也不詳述了。code
下面下面是個人代碼:blog
std::string system_contract::get_public_key_from_array(const char* pub, const int len) { std::string result; checksum160 ck; ripemd160(pub, len, &ck); std::vector<unsigned char> vec; for(int i = 0; i < len; ++i) { vec.push_back(pub[i]); } for(int i = 0; i < 4; ++i ) { vec.push_back(ck.hash[i]); } result = "UOS" + EncodeBase58(vec); print("result: ", result, "\n"); return result; } std::string system_contract::EncodeBase58(const std::vector<unsigned char>& vch) { return EncodeBase58(vch.data(), vch.data() + vch.size()); } std::string system_contract::EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) { // Skip & count leading zeroes. int zeroes = 0; int length = 0; while (pbegin != pend && *pbegin == 0) { pbegin++; zeroes++; } // Allocate enough space in big-endian base58 representation. int size = (pend - pbegin) * 138 / 100 + 1; // log(256) / log(58), rounded up. std::vector<unsigned char> b58(size); // Process the bytes. while (pbegin != pend) { int carry = *pbegin; int i = 0; // Apply "b58 = b58 * 256 + ch". for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); (carry != 0 || i < length) && (it != b58.rend()); it++, i++) { carry += 256 * (*it); *it = carry % 58; carry /= 58; } assert(carry == 0); length = i; pbegin++; } // Skip leading zeroes in base58 result. std::vector<unsigned char>::iterator it = b58.begin() + (size - length); while (it != b58.end() && *it == 0) it++; // Translate the result into a string. std::string str; str.reserve(zeroes + (b58.end() - it)); str.assign(zeroes, '1'); while (it != b58.end()) str += pszBase58[*(it++)]; return str; }
個人合約裏調用此接口的部分代碼:接口
接口的調用:ip
cluos -u http://10.186.11.112:8000 push action uosio setbplist '{"bp_name":"marsaccount3","bp_time":"1553685636", "hash_bplist":"9d3329c56e7e6f6068f7dbd905f4b99ffa86ba53897c2a399f5d3637ade41c9a", "bplist":[{"producer_name":"marsaccount3", "block_signing_key":"UOS6aWfdf6tHWCepZpP6MzdynuNMAkNKr6nbNMguTuCatq88LyG4G"},{"producer_name":"dragonexsafe", "block_signing_key":"UOS7DVNg9bsq1zUZtUbWwA1UyhaqFBmNrCRVnPFeGYgsx7kzfAtiC"},{"producer_name":"uosvegasjack", "block_signing_key":"UOS5aTdkbRaPH5WKYPJaxX8HfqGtX8hKx8p6FDPAzpkyJiYnuBu5c"}]}' -x 2000 -p marsaccount3@active
能夠看到個人三個公匙是:get
UOS6aWfdf6tHWCepZpP6MzdynuNMAkNKr6nbNMguTuCatq88LyG4G
UOS7DVNg9bsq1zUZtUbWwA1UyhaqFBmNrCRVnPFeGYgsx7kzfAtiC
UOS5aTdkbRaPH5WKYPJaxX8HfqGtX8hKx8p6FDPAzpkyJiYnuBu5c
但實際到了EOS合約裏面,已經被處理過了,像第一個公匙 UOS6aWfdf6tHWCepZpP6MzdynuNMAkNKr6nbNMguTuCatq88LyG4G 在傳到合約裏對應的就是33個字節的數據,以十六進制打印出來就是 02de9288d61afea6084227b2db9449fd58986652bcda91a4efeeac3ef0ee4ad80c原型
經過以上的接口就還原公匙的原型了。string
參考來源:https://www.liaoxuefeng.com/article/001523444489789210f7acb0355485d91cfb1a44788ac9b000