Moralis 计费和费率限制
防止滥用
如果您开始收到 Cloudflare 错误,例如 Cloudflare 错误 1020 - 很可能您被我们的滥用预防系统标记,并且 Cloudflare 代表我们阻止了您的访问。
您可能还会看到其他错误消息。
以下是您被暂时禁止的几种情况。
- 如果您正在发送请求,尽管您的密钥已经受到速率限制,我们可能会暂时禁止您。 例如,假设您的计划允许您每秒执行 30 个请求。 如果您尝试在同一秒内发出 200 个请求 - 您很可能会被暂时禁止。
- 每个项目使用一个密钥。 例如,如果您创建 100 个免费帐户并使用这些帐户的密钥发送请求 - 与同一项目相关的所有帐户都将被禁止。
- 如果您认为自己被错误地暂时禁止,请发送电子邮件至 hello@moralis.io,我们会尽快为您提供帮助。
如何避免被封号?
- 不要使用超过 1 个 Moralis 帐户。
- 在您的应用程序中实施速率限制逻辑,这样您就不会尝试执行超出计划允许的请求。
- 如果您有任何问题,请发送电子邮件至 hello@moralis.io。
请求权重
所有 Moralis 计划对您每月可以提出的请求数量都有很大的限制。 您有多少包含的请求取决于您拥有的计划,请查看定价页面了解更多详细信息。
在大多数情况下,对 Speedy Nodes 或 Web3 API 的一次请求计为对您的每月配额或允许的速率限制的一次请求。
但是,一些 Speedy Node 方法和 API 请求的计算量非常大,因此算作多个请求。
通过给予一些繁重的要求更高的权重,我们确保您只为使用的东西付费,而不是多花一分钱 - 期间! 通过这种方式,您可以获得大多数用例的廉价请求,同时我们可以通过权衡计算成本高昂的端点来保护我们的系统免受滥用。
有关加权的 Speedy Node 方法和 API 端点的详细信息,请参阅下表。
快速节点请求
Moralis Speedy 节点的请求限制为每批 50 个请求。
Method |
Cost |
eth_maxPriorityFeePerGas |
1 request |
eth_getTransactionReceipt |
2 requests |
eth_getUncleByBlockHashAndIndex |
2 requests |
eth_getUncleByBlockNumberAndIndex |
2 requests |
eth_getTransactionByBlockHashAndIndex |
2 requests |
eth_getTransactionByBlockNumberAndIndex |
2 requests |
eth_getUncleCountByBlockHash |
2 requests |
eth_getUncleCountByBlockNumber |
2 requests |
web3_clientVersion |
2 requests |
web3_sha3 |
2 requests |
eth_getBlockByNumber |
2 requests |
eth_getStorageAt |
2 requests |
eth_getTransactionByHash |
2 requests |
trace_get |
2 requests |
eth_gasPrice |
2 requests |
eth_getBalance |
2 requests |
eth_getCode |
2 requests |
eth_getFilterChanges |
2 requests |
eth_newBlockFilter |
2 requests |
eth_newFilter |
2 requests |
eth_newPendingTransactionFilter |
2 requests |
eth_getBlockTransactionCountByHash |
2 requests |
eth_getBlockTransactionCountByNumber |
2 requests |
eth_getProof |
2 requests |
eth_getBlockByHash |
2 requests |
trace_block |
3 requests |
parity_getBlockReceipts |
3 requests |
eth_getTransactionCount |
3 requests |
eth_call |
3 requests |
trace_transaction |
3 requests |
eth_getFilterLogs |
8 requests |
eth_getLogs |
8 requests |
trace_call |
8 requests |
trace_callMany |
8 requests |
trace_rawTransaction |
8 requests |
trace_filter |
8 requests |
eth_estimateGas |
9 requests |
eth_sendRawTransaction |
25 requests |
debug_traceTransaction |
31 requests |
trace_replayTransaction |
298 requests |
trace_replayBlockTransactions |
298 requests |
API 请求
Path |
Weight |
/info/endpointWeights |
0 request |
/{address} |
1 request |
/{address}/balance |
1 request |
/erc20/metadata |
1 request |
/erc20/metadata/symbols |
1 request |
/erc20/{address}/allowance |
1 request |
/resolve/{domain} |
1 request |
/{pair_address}/reserves |
1 request |
/resolve/{address}/reverse |
1 request |
/web3/version |
1 request |
/{address}/events |
2 requests |
/{address}/erc20/transfers |
2 requests |
/erc20/{address}/transfers |
2 requests |
/block/{block_number_or_hash}/nft/transfers |
2 requests |
/nft/{address}/{token_id} |
2 requests |
/nft/{address}/{token_id}/transfers |
2 requests |
/{address}/logs |
2 requests |
/{address}/function |
2 requests |
/{address} |
2 requests |
/erc20/{address}/price |
3 requests |
/nft/{address}/trades |
4 requests |
/nft/{address}/lowestprice |
4 requests |
/{address}/erc20 |
5 requests |
/block/{block_number_or_hash} |
5 requests |
/nft/search |
5 requests |
/{address}/nft |
5 requests |
/{address}/nft/transfers |
5 requests |
/{address}/nft/{token_address} |
5 requests |
/nft/{address} |
5 requests |
/nft/{address}/transfers |
5 requests |
/nft/{address}/owners |
5 requests |
/nft/{address}/metadata |
5 requests |
/nft/{address}/sync |
5 requests |
/nft/{address}/{token_id}/metadata/resync |
5 requests |
/nft/transfers |
5 requests |
/nft/{address}/{token_id}/owners |
20 requests |
注意:对于确切的速率限制值,可以使用端点 https://deep-index.moralis.io/api/v2/info/endpointWeights
。
注意:/nft/{address}/{token_id}/metadata/resync
的计费成本为 5,速率限制成本为 25,这意味着您可以使用免费套餐每秒调用一次,使用免费套餐每秒只能调用两次 专业计划
输出示例:
[
{
"endpoint": "getBlock",
"path": "/block/{block_number_or_hash}",
"price": 1
},
{
"endpoint": "getContractEvents",
"path": "/{address}/events",
"price": 2
},
{
"endpoint": "getTransactions",
"path": "/{address}",
"price": 1
},
...
{
"endpoint": "endpointWeights",
"path": "/info/endpointWeights",
"price": 0
}
]
为什么我的费率有限?
您需要了解两种不同类型的速率限制。
在 SDK 中使用 Moralis.Web3API 时的速率限制
错误 141 - 服务器和客户端之间的速率限制
第一种速率限制是保护您的 Moralis 服务器免受来自客户端的垃圾邮件请求。
如您所知 - 任何人都可以使用 Moralis SDK 并使用您的服务器调用 Web3 API。
您的服务器具有内置的速率限制,您可以对其进行调整,以指示不同类型的用户在受到速率限制之前可以执行多少请求。 您可以完全控制这些速率限制,并且可以使用 Cloud Code 中的几行代码对其进行调整。
如果您的客户超出您设置的允许速率限制,他们将看到以下错误:
错误 141:来自该特定客户端的 Web3API 请求过多,客户端需要等待才能发送更多请求。
这可以使用 Moralis.settings.setAPIRateLimit
进行调整。
何时可能发生此错误:
想象一下使用您的网站的特定用户试图在同一分钟内发出大量请求。 您的服务器将保护自己并拒绝用户。 只有特定用户会受到影响。
解决此错误的方法是调整您的设置,如上所述。
错误 141 - Moralis 服务器和 Web3 API 之间的速率限制
当您的用户从 SDK 调用 Web3 API 时,他们可能不受您的服务器的速率限制(上述情况),但由于您的计划,他们可能会受到速率限制。
错误 141:此 Moralis 服务器由于计划限制而受到速率限制。
何时可能发生此错误:
您有许多用户并没有单独提出太多请求,但他们共同提出的请求超出了您的计划允许的范围。 例如 - 您的计划允许每分钟 1000 个请求。 您有 100 个用户每分钟执行 15 个请求。
解决此错误的方法是升级您的 Moralis 计划。
使用 HTTP 调用 Web3 API 时的速率限制
错误 429 - 非 Moralis 服务器和 Web3 API 之间的速率限制
当您从自己的非 Moralis 后端调用 Web3 API 时,您可能会受到 Web3 API 的限制。
在这种情况下,您将收到错误 429:超出速率限制。
要查看的最重要的值是 x-rate-limit-limit
和 x-rate-limit-throttle-limit
。
第一个告诉您每分钟允许执行多少个请求,第二个告诉您每秒可以执行多少个请求。
一些繁重的请求算作多个请求。
为了不受到速率限制,请注意 x-rate-limit-used
和 x-rate-throttle-used
。
解决此错误的方法是升级您的 Moralis 计划。
如何使用cursor(nodejs)的示例
const Moralis = require("moralis/node");
const serverUrl = "https://server_domain:2053/server";
const appId = "app id";
const contractAddress = "contract address";
async function getAllOwners() {
await Moralis.start({ serverUrl: serverUrl, appId: appId });
let cursor = null;
let owners = {};
do {
const response = await Moralis.Web3API.token.getNFTOwners({
address: contractAddress,
chain: "eth",
limit: 500,
cursor: cursor,
});
console.log(
`Got page ${response.page} of ${Math.ceil(
response.total / response.page_size
)}, ${response.total} total`
);
for (const owner of response.result) {
owners[owner.owner_of] = {
amount: owner.amount,
owner: owner.owner_of,
tokenId: owner.token_id,
tokenAddress: owner.token_address,
};
}
cursor = response.cursor;
} while (cursor != "" && cursor != null);
console.log("owners:", owners, "total owners:", Object.keys(owners).length);
}
getAllOwners();
如何使用cursor的示例(python)
import requests
import time
def get_nft_owners(offset, cursor):
print("offset", offset)
url = 'https://deep-index.moralis.io/api/v2/nft/<address_here>/owners?chain=polygon&format=decimal'
if cursor:
url = url + "&cursor=%s" % cursor
print("api_url", url)
headers = {
"Content-Type": "application/json",
"X-API-Key": "API_KEY_HERE"
}
statusResponse = requests.request("GET", url, headers=headers)
data = statusResponse.json()
print("HTTP headers:", statusResponse.headers)
try:
print("nr results", len(data['result']))
except:
print(repr(data))
print("exiting")
raise SystemExit
cursor = data['cursor']
print(data['page'], data['total'])
return cursor
cursor = None
for j in range(0, 10):
cursor = get_nft_owners(j*500, cursor)
print()
time.sleep(1.1)