比特币 RPC 命令「walletpassphrase」
$ bitcoin-cli help walletpassphrase walletpassphrase "passphrase" timeout 把钱包解密密钥存储在内存中的“超时”秒数。 在执行与私钥相关的交易前需要这样,如发送比特币 参数: 1. "passphrase"(字符串,必备)钱包密码 2. timeout (整型,必备)保留解密密钥的以秒为单位的时间。 注: 在钱包已解锁的情况下发处 walletpassphrase 命令将设置一个覆盖旧解锁时间的新解锁时间。 例子: 解锁钱包 60 秒 > bitcoin-cli walletpassphrase "my pass phrase" 60 再次锁定钱包(60 秒前) > bitcoin-cli walletlock 作为 json rpc 调用 > curl --user myusername:mypassword --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "walletpassphrase", "params": ["my pass phrase", 60] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/
源码剖析
walletpassphrase
对应的函数在文件 rpcserver.h
中被引用。
extern UniValue walletpassphrase(const UniValue& params, bool fHelp);
实现在文件 rpcwallet.cpp
中。
UniValue walletpassphrase(const UniValue& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp)) // 1. 确保钱包可用
return NullUniValue;
if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
throw runtime_error(
"walletpassphrase \"passphrase\" timeout\n"
"\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
"This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
"\nArguments:\n"
"1. \"passphrase\" (string, required) The wallet passphrase\n"
"2. timeout (numeric, required) The time to keep the decryption key in seconds.\n"
"\nNote:\n"
"Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
"time that overrides the old one.\n"
"\nExamples:\n"
"\nunlock the wallet for 60 seconds\n"
+ HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
"\nLock the wallet again (before 60 seconds)\n"
+ HelpExampleCli("walletlock", "") +
"\nAs json rpc call\n"
+ HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
); // 2. 帮助内容
LOCK2(cs_main, pwalletMain->cs_wallet);
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
// Note that the walletpassphrase is stored in params[0] which is not mlock()ed
SecureString strWalletPass; // 注意 walletpassphrase 存储在 params[0] 中,而不是 mlock()ed
strWalletPass.reserve(100);
// TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
// Alternately, find a way to make params[0] mlock()'d to begin with.
strWalletPass = params[0].get_str().c_str();
if (strWalletPass.length() > 0)
{
if (!pwalletMain->Unlock(strWalletPass))
throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
}
else
throw runtime_error(
"walletpassphrase <passphrase> <timeout>\n"
"Stores the wallet decryption key in memory for <timeout> seconds.");
pwalletMain->TopUpKeyPool(); // 充满密钥池
int64_t nSleepTime = params[1].get_int64();
LOCK(cs_nWalletUnlockTime);
nWalletUnlockTime = GetTime() + nSleepTime;
RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime); // 3. 创建锁定钱包线程
return NullUniValue;
}
1. 确保钱包可用
参考比特币 RPC 命令「fundrawtransaction」1. 确保钱包可用。
2. 帮助内容
参考比特币 RPC 命令「getbestblockhash」1. 帮助内容。
3. 创建锁定钱包线程
创建线程函数 RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime)
声明在文件 rpcserver.h
中。
/**
* Run func nSeconds from now.
* Overrides previous timer <name> (if any).
*/
void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds);
从现在开始运行函数 nSeconds 秒。 覆盖上一个定时器 <name>(如果有)。
定义在文件 rpcserver.cpp
中。
void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds)
{
if (timerInterfaces.empty())
throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC");
deadlineTimers.erase(name); // 擦除指定名字的定时器
RPCTimerInterface* timerInterface = timerInterfaces.back(); // 取列表中最后一个定时器
LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name());
deadlineTimers.insert(std::make_pair(name, boost::shared_ptr<RPCTimerBase>(timerInterface->NewTimer(func, nSeconds*1000)))); // 和定时器名字配对,插入到截止时间定时器映射列表中
}
定时器接口列表 timerInterfaces
和定时器映射列表 deadlineTimers
的定义在文件 rpcserver.cpp
中。
/* Timer-creating functions */
static std::vector<RPCTimerInterface*> timerInterfaces; // 定时器创建函数
/* Map of name to timer.
* @note Can be changed to std::unique_ptr when C++11 */
static std::map<std::string, boost::shared_ptr<RPCTimerBase> > deadlineTimers; // 定时器名字映射。