让我们谈谈Web3集成!

Moralis附带了一组插件,可帮助您专注于应用程序的开发,剩下的交给我们。

类似于​window.ethereum.enable()​但返回一个从Ethers.js解析为​web3Provider​实例的promise。当您需要一个功能齐全的​web3Provider​实例时使用它,例如进行合约调用。

注意:确保安装了v1.0.0或更高版本的SDK。否则​Moralis.enableWeb3()​将返回web3.js的实例而不是ethers.js

例如:

// Get a (ethers.js) web3Providerconst web3Provider = await Moralis.enableWeb3();

有关如何使用Ethers.js的更多信息,请参阅Ethers.js文档

Web3.js

您可能想要使用另一个库,例如Web3.js。为此,您需要将此库包含到您的代码中。

当您通过html导入javascript脚本时:

<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js" rel="external nofollow" ></script>

或者当您使用包管理器时:

npm install web3

然后在您的代码中,使用​Moralis.provider​来初始化web3.js库。​Moralis.provider​只会在调用​Moralis.authenticate​或​Moralis.enableWeb3​后设置。

import Web3 from "web3"; // Only when using npm/yarn// Enable web3 and get the initialized web3 instance from Web3.jsawait Moralis.enableWeb3();const web3Js = new Web3(Moralis.provider);

有关如何使用web3.js的更多信息,请参阅Web3.js文档

注意:Ethers.js包含在MoralisSDK中。因此​Moralis.executeFunction​和​Moralis.transfer​的函数响应将始终由Ethers.js格式化(更多信息见下文)

获取EthersJs库

您可以访问Moralis正在使用的Ethers.js库:

const ethers = Moralis.web3Library;

有了这个实例,你可以使用Ethers.js中的任何方法,例如:

const ethers = Moralis.web3Library;const daiAddress = "dai.tokens.ethers.eth";const daiAbi = [  "function name() view returns (string)",  "function symbol() view returns (string)",  "function balanceOf(address) view returns (uint)",  "function transfer(address to, uint amount)",  "event Transfer(address indexed from, address indexed to, uint amount)",];const daiContract = new ethers.Contract(daiAddress, daiAbi, provider);const name = await daiContract.name();console.log(name);// 'Dai Stablecoin'

有关如何使用Ethers.js的更多信息,请参阅Ethers.js文档

连接器

您可以使用任何连接器(例如​WalletConnect​、​Metamask​、​Network​等)启用web3,与使用​Moralis.authenticate​的方式相同),使用​provider​选项:

const web3 = await Moralis.enableWeb3({ provider: "walletconnect" });

NodeJs环境

在nodejs环境中使用moralis时,您可以选择使用私钥选项来签署交易:

const web3 = await Moralis.enableWeb3({ privateKey: "your_private_key" });

在云函数中

也可以在云函数中获取Web3实例,但语法有点不同。

这个实例是一个Web3.js实例

执行函数

通过​executeFunction​,您可以执行只读(查看)函数和编写方法。他们都给出了略有不同的回应。所以我们在下面分别处理它们。

选项:

contractAddress​(必填):智能合约地址 ​abi​(必填):合约或函数ABI(应作为数组提供) ​functionName​(必需):函数名称 ​params​(必需):您的特定功能所需的参数 ​msgValue​(可选):数字|字符串|BN|BigNumber。wei为交易转移的价值

只读函数

对于只读函数,您需要等待执行完成。然后你直接得到结果。

const ABI = [  {    inputs: [],    name: "message",    outputs: [      {        internalType: "string",        name: "",        type: "string",      },    ],    stateMutability: "view",    type: "function",  },  {    inputs: [      {        internalType: "string",        name: "_newMessage",        type: "string",      },    ],    name: "setMessage",    outputs: [],    stateMutability: "nonpayable",    type: "function",  },];const readOptions = {  contractAddress: "0xe...56",  functionName: "message",  abi: ABI,};const message = await Moralis.executeFunction(readOptions);console.log(message);// -> "Hello World"

需要启用的web3提供程序。在执行该功能之前,请确保在您的钱包中选择了正确的网络。

您可以使用我们的Web3API在没有活跃的web3提供者的情况下接收此信息:​Moralis.Web3API.token.getAllowance()

调用写合约方法的示例

通过​setMessage​函数调用设置消息的示例。

const ABI = [  {    inputs: [],    name: "message",    outputs: [      {        internalType: "string",        name: "",        type: "string",      },    ],    stateMutability: "view",    type: "function",  },  {    inputs: [      {        internalType: "string",        name: "_newMessage",        type: "string",      },    ],    name: "setMessage",    outputs: [],    stateMutability: "nonpayable",    type: "function",  },];const sendOptions = {  contractAddress: "0xe...56",  functionName: "setMessage",  abi: ABI,  params: {    _newMessage: "Hello Moralis",  },};const transaction = await Moralis.executeFunction(sendOptions);console.log(transaction.hash);// --> "0x39af55979f5b690fdce14eb23f91dfb0357cb1a27f387656e197636e597b5b7c"// Wait until the transaction is confirmedawait transaction.wait();// Read new valueconst message = await Moralis.executeFunction(readOptions);console.log(message);// --> "Hello Moralis"

您将从Ethers.js获得交易响应,其中包括哈希和其他信息。

交易响应示例

{    "hash": "0x39af55979f5b690fdce14eb23f91dfb0357cb1a27f387656e197636e597b5b7c",    "type": 2,    "accessList": null,    "blockHash": null,    "blockNumber": null,    "transactionIndex": null,    "confirmations": 0,    "from": "0xab5801a7d398351b8be11c439e05c5b3259aec9b",    "gasPrice": {        "type": "BigNumber",        "hex": "0x04cf1ef09a"    },    "maxPriorityFeePerGas": {        "type": "BigNumber",        "hex": "0x908a9040"    },    "maxFeePerGas": {        "type": "BigNumber",        "hex": "0x04cf1ef09a"    },    "gasLimit": {        "type": "BigNumber",        "hex": "0x75c0"    },    "to": "0x73bceb1cd57c711feac4224d062b0f6ff338501e",    "value": {        "type": "BigNumber",        "hex": "0x00"    },    "nonce": 13,    "data": "0x368b877200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004486f6c6100000000000000000000000000000000000000000000000000000000",    "r": "0x8b00442b141406a1b5d701c7ac6ab3b6adec13010fdc1218a42f8f9aa8e57718",    "s": "0x1abc60ae4de7af8bcba4d1b44e470f40a04c3c632fd4a75f87a553820a43ddef",    "v": 1,    "creates": null,    "chainId": 0}

如果你想等到交易被链确认,那么你可以调用transaction.wait()。这将解析为交易收据。此收据还将包括交易中已触发的所有事件的日志。例如,我们在这里等待3个确认:

const receipt = await transaction.wait(3);

收据示例

{    "to": "0x73bceb1cd57c711feac4224d062b0f6ff338501e",    "from": "0xab5801a7d398351b8be11c439e05c5b3259aec9b",    "contractAddress": null,    "transactionIndex": 72,    "gasUsed": {        "type": "BigNumber",        "hex": "0x75b2"    },    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",    "blockHash": "0x746d7d42e8022f560577dfdc0150e1e8b009e59c537a9053a82e9ad6d20f6d06",    "transactionHash": "0x39af55979f5b690fdce14eb23f91dfb0357cb1a27f387656e197636e597b5b7c",    "logs": [],    "blockNumber": 11847564,    "confirmations": 2,    "cumulativeGasUsed": {        "type": "BigNumber",        "hex": "0x6743ab"    },    "effectiveGasPrice": {        "type": "BigNumber",        "hex": "0x04623af60c"    },    "status": 1,    "type": 2,    "byzantium": true,    "events": []}

在合约方法示例中传输本机加密

例如,您想调用一个智能合约方法,将本机加密货币换成代币。这种情况与您使用​ERC20​代币并指定要用作方法参数的代币数量的通常情况不同。在智能合约中使用原生加密货币的操作假定您将随交易一起转移一些价值。在solidity中,您可以将其称为​msg.value

const options = {  contractAddress: "0xe...56",  functionName: "swapNativeForTokens",  abi: ABI,  msgValue: Moralis.Units.ETH("0.1"),};const transaction = await Moralis.executeFunction(options);const receipt = await transaction.wait();console.log(receipt);

创建可重用选项的示例

您可以使用此构造来创建可重用的选项来调用多个合约方法。

const options = {  contractAddress: "0xe...56",  abi: ABI,};const symbol = await Moralis.executeFunction({  functionName: "symbol",  ...options,});const decimals = await Moralis.executeFunction({  functionName: "decimals",  ...options,});const name = await Moralis.executeFunction({  functionName: "name",  ...options,});

解析交易结果

Moralis.executeFunction()​返回:

如果函数是只读的,则返回值 如果函数在链上写入,则为交易响应。

您可以通过等待交易得到确认,将交易响应解析为收据。例如,要等待3次确认:

const options = {  contractAddress: "0xe...56",  functionName: "swapNativeForTokens",  abi: ABI,  msgValue: Moralis.Units.ETH("0.1"),};const transaction = await Moralis.executeFunction(options);const result = await transaction.wait();

事件

您可以在Moralis上监听几个事件,以检查用户的web3连接:

onWeb3EnabledonWeb3DeactivatedonChainChangedonAccountChangedonConnect(firedfromtheEIP1193provider)onDisconnect(firedfromtheEIP1193provider)

Moralis.onWeb3Enabled()

当用户连接到链时监听事件(通过​Moralis.authenticate()​/​Moralis.enableWeb3()​):

// Subscribe to onWeb3Enabled eventsconst unsubscribe = Moralis.onWeb3Enabled((result) => {  console.log(result);});// Unsubscribe to onWeb3Enabled eventsunsubscribe();

结果对象

{  account: '0x1a2b3c4d....',  chain: '0x1',  connector: {} // the connector instance  web3: {} // the Ethers.js web3 instance  provider: {} // the EIP1193-provider, used to connect}

Moralis.onWeb3Deactivated()

当用户断开连接时监听事件(通过Moralis.deactivateWeb3()):

// Subscribe to onWeb3Deactivated eventsconst unsubscribe = Moralis.onWeb3Deactivated((result) => {  console.log(result);});// Unsubscribe to onWeb3Deactivated eventsunsubscribe();

结果对象

{  connector: {  } // the connector instance  provider: {  } // the EIP1193-provider, used to connect}

Moralis.onChainChanged()

在启用web3后,当用户更改链时监听事件。

// Subscribe to onChainChanged eventsconst unsubscribe = Moralis.onChainChanged((chain) => {  console.log(chain);  // returns the new chain --> ex. "0x1"});// Unsubscribe to onChainChanged eventsunsubscribe();

Moralis.onAccountChanged()

在启用web3后,在用户更改帐户时监听事件。

// Subscribe to onAccountChanged eventsconst unsubscribe = Moralis.onAccountChanged((chain) => {  console.log(chain);  // returns the new account --> ex. "0x1a2b3c4d..."});// Unsubscribe to onAccountChanged eventsunsubscribe();

Moralis.onConnect()

您可能想改用​Moralis.onWeb3Activated​,因为它更一致,并且由Moralis处理,而不是EIP-1193提供程序

当提供者触发连接事件时监听事件。

从规范:

Provider在以下情况下发出连接:

初始化后首先连接到一个链。在发出断开事件后,首先连接到链。
// Subscribe to onConnect eventsconst unsubscribe = Moralis.onConnect((provider) => {  console.log(provider);  // returns the EIP-1193 provider});// Unsubscribe to onConnect eventsunsubscribe();

Moralis.onDisconnect()

您可能想改用​Moralis.onWeb3Deactivated​,因为它更一致,并且由Moralis处理,而不是EIP-1193提供程序

当提供者触发断开事件时监听事件。

从规范:

Provider在与所有链断开连接时发出断开连接

// Subscribe to onDisconnect eventsconst unsubscribe = Moralis.onDisconnect((error) => {  console.log(error);  // returns a ProviderRpcError});// Unsubscribe to onDisconnect eventsunsubscribe();

要监听这些事件,您只需调用​Moralis.onXXX​。例如:

const unsubscribe = Moralis.onAccountChanged(function (account) {  console.log(account);});// "0x1a2b3c4d..."

Metamask(和其他钱包)事件

如果您想在连接用户之前(在元掩码上)侦听事件,那么您可能希望直接从元掩码侦听事件

https://docs.metamask.io/guide/ethereum-provider.html#events

例如

window.ethereum.on('accountsChanged' (accounts) => {  console.log(accounts)  // --> [0x1a2b3c4d...]})

其他钱包也有类似的实现,请查看各自钱包的文档。

链接

将地址链接(取消链接)到当前用户。

link(address)unlink(address)

用户可能有多个他们希望与他们的个人资料相关联的地址。这可以在用户通过身份验证后使用链接功能完成。

Moralis.onAccountChanged(async function (account) {  const confirmed = confirm("Link this address to your account?");  if (confirmed) {    await Moralis.link(account);    alert("Address added!");  }});

取消链接功能从用户的个人资料中删除给定的地址。

await Moralis.unlink(address);

更改链接消息

可以通过提供​signingMessage​选项来更改用户在将地址链接到当前用户时看到的消息:

await Moralis.link(accounts[0], { signingMessage: "Custom Linking Message" });

ensureWeb3IsInstalled

检测是否激活了web3提供程序。

返回:TrueorFalse

const isWeb3Active = Moralis.ensureWeb3IsInstalled();if (isWeb3Active) {  console.log("Activated");} else {  await Moralis.enable();}

停用Web3

停用当前的web3连接

      await Moralis.enableWeb3();      console.log("ENABLED", Moralis.isWeb3Enabled());      await Moralis.deactivateWeb3();      console.log("DISABLED", Moralis.isWeb3Enabled());

连接器/连接器类型

返回连接器或连接器类型的详细信息,用于验证或启用web3:

const connectorType = Moralis.Web3.connectorType;if (connectorType === "injected") {  console.log("Metamask or an injected provider is used");}const connector = Moralis.Web3.connector;console.log(connector);

链ID

返回用于连接web3的当前链ID

const chainId = await Moralis.chainId;console.log(chainId); // 56

帐户

返回用于连接到web3的当前帐户

更改网络

改变当前网络的功能

注意:此方法只能在Metamask用作连接器时使用

选项:

chain​(必填):要切换到的链id。接受数字或十六进制字符串中的值。有效值列在交易和余额部分的介绍页面上。示例:56、“0x38”
const chainId = "0x1"; //Ethereum Mainnetconst chainIdHex = await Moralis.switchNetwork(chainId);

您只能切换到钱包中的网络。如何添加新网络,您可以在下面找到。

添加网络

注意:此方法只能在Metamask用作连接器时使用

将新网络添加到钱包的功能。您可以在他们的文档站点中找到每个链的网络配置。

选项:

chainid​(必填):网络链ID ​chainName​(必填):网络名称 ​currencyName​(必填):本币名称 ​currencySymbol​(必填):货币符号 ​rpcUrl​(必填):新的RPCURL ​blockExplorerUrl​(必填):块浏览器URL
const chainId = 43114;const chainName = "Avalanche Mainnet";const currencyName = "AVAX";const currencySymbol = "AVAX";const rpcUrl = "https://api.avax.network/ext/bc/C/rpc";const blockExplorerUrl = "https://cchain.explorer.avax.network/";await Moralis.addNetwork(  chainId,  chainName,  currencyName,  currencySymbol,  rpcUrl,  blockExplorerUrl);