代码拉取完成,页面将自动刷新
同步操作将从 楠木/etherscan-api 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*
* Copyright (c) 2018 LI Zhennan
*
* Use of this work is governed by a MIT License.
* You may find a license copy in project root.
*/
package etherscan
import (
"fmt"
"os"
"testing"
"time"
)
const apiKeyEnvName = "ETHERSCAN_API_KEY"
var (
// api test client for many test cases
api *Client
// bucket default rate limiter
bucket *Bucket
// apiKey etherscan API key
apiKey string
)
func init() {
apiKey = os.Getenv(apiKeyEnvName)
if apiKey == "" {
panic(fmt.Sprintf("API key is empty, set env variable %q with a valid API key to proceed.", apiKeyEnvName))
}
bucket = NewBucket(500 * time.Millisecond)
api = New(Mainnet, apiKey)
api.Verbose = true
api.BeforeRequest = func(module string, action string, param map[string]interface{}) error {
bucket.Take()
return nil
}
}
// Bucket is a simple and easy rate limiter
// Use NewBucket() to construct one.
type Bucket struct {
bucket chan bool
refillTime time.Duration
}
// NewBucket factory of Bucket
func NewBucket(refillTime time.Duration) (b *Bucket) {
b = &Bucket{
bucket: make(chan bool),
refillTime: refillTime,
}
go b.fillRoutine()
return
}
// Take a action token from bucket,
// blocks if there is currently no token left.
func (b *Bucket) Take() {
<-b.bucket
}
// fill a action token into bucket,
// no-op if the bucket is currently full
func (b *Bucket) fill() {
b.bucket <- true
}
func (b *Bucket) fillRoutine() {
ticker := time.NewTicker(b.refillTime)
for range ticker.C {
b.fill()
}
}
// noError checks for testing error
func noError(t *testing.T, err error, msg string) {
if err != nil {
t.Fatalf("%s: %v", msg, err)
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。