Go-Ethereum

節點啟動後如何以程式方式解鎖帳戶?

  • January 16, 2017

有什麼方法可以在不打開控制台的情況下解鎖帳戶geth

我正在編寫一些腳本來自動化集群生成,我希望我可以呼叫geth解鎖一些帳戶,而無需啟動另一個實例或附加到現有實例。


編輯

如果我執行類似:

geth --genesis "$GENESIS_FILE" --datadir "$DATA_DIR" --networkid "$NETWORK_ID" \
    --password <(echo -n $ACCOUNT_PASSWD) --unlock "$UNLOCK_INDEXES" \
    --exec '""' attach > /dev/null

節點啟動後,賬戶未解鎖

我設法解鎖帳戶的唯一方法是在執行時解鎖它們geth以啟動節點。

只是為了澄清:

  • 您想執行一個 geth 節點,並在預設情況下所有帳戶都被鎖定
  • 您稍後想要執行“geth attach”命令來解鎖一個或多個帳戶一段時間

您可以使用以下命令附加到您的 geth 節點,以使用 personal.unlockAccount(…) JavaScript API 解鎖帳戶(https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console# personalunlockaccount),其中第三個參數是以秒為單位的持續時間:

> geth --exec "personal.unlockAccount(eth.accounts[0], 'password', 1000)" attach
true

或者您可以創建一個文件,例如 unlock.js 具有以下內容:

personal.unlockAccount(eth.accounts[0], 'password', 1000);

然後使用以下命令解鎖帳戶:

> geth --exec "loadScript('unlock.js')" attach
true

回答以下有關預設持續時間的問題,如果未指定持續時間,則暗示持續時間為 0。並且持續時間為 0 將解鎖帳戶,直到程序退出,例如沒有到期。

來自https://github.com/ethereum/go-ethereum/blob/master/internal/ethapi/api.go#L239-L254

// UnlockAccount will unlock the account associated with the given address with
// the given password for duration seconds. If duration is nil it will use a
// default of 300 seconds. It returns an indication if the account was unlocked.
func (s *PrivateAccountAPI) UnlockAccount(addr common.Address, password string, duration *uint64) (bool, error) {
   const max = uint64(time.Duration(math.MaxInt64) / time.Second)
   var d time.Duration
   if duration == nil {
       d = 300 * time.Second
   } else if *duration > max {
       return false, errors.New("unlock duration too large")
   } else {
       d = time.Duration(*duration) * time.Second
   }
   err := s.am.TimedUnlock(accounts.Account{Address: addr}, password, d)
   return err == nil, err
}

https://github.com/ethereum/go-ethereum/blob/master/accounts/account_manager.go#L181-L216可以看到評論A timeout of 0 unlocks the account until the program exits

// TimedUnlock unlocks the given account with the passphrase. The account
// stays unlocked for the duration of timeout. A timeout of 0 unlocks the account
// until the program exits. The account must match a unique key file.
//
// If the account address is already unlocked for a duration, TimedUnlock extends or
// shortens the active unlock timeout. If the address was previously unlocked
// indefinitely the timeout is not altered.
func (am *Manager) TimedUnlock(a Account, passphrase string, timeout time.Duration) error {
   a, key, err := am.getDecryptedKey(a, passphrase)
   if err != nil {
       return err
   }

   am.mu.Lock()
   defer am.mu.Unlock()
   u, found := am.unlocked[a.Address]
   if found {
       if u.abort == nil {
           // The address was unlocked indefinitely, so unlocking
           // it with a timeout would be confusing.
           zeroKey(key.PrivateKey)
           return nil
       } else {
           // Terminate the expire goroutine and replace it below.
           close(u.abort)
       }
   }
   if timeout > 0 {
       u = &unlocked{Key: key, abort: make(chan struct{})}
       go am.expire(a.Address, u, timeout)
   } else {
       u = &unlocked{Key: key}
   }
   am.unlocked[a.Address] = u
   return nil
}

引用自:https://ethereum.stackexchange.com/questions/2678