gpt4 book ai didi

swift - 如何从 Swift 应用程序与部署在区 block 链上的智能合约进行交互

转载 作者:行者123 更新时间:2023-12-05 04:47:07 55 4
gpt4 key购买 nike

这是我第一次使用智能合约,我的目标是创建一个可以通过调用保存或检索数据的方法与之交互的移动应用程序。出于这个原因,我使用 Remix 创建了一个非常简单的合约,并且我还在 Rinkeby 测试网上进行了部署。

contract Storage {

uint256 number;

function store(uint256 num) public {
number = num;
}

function retrieve() public view returns (uint256){
return number;
}
}

然后我构建了一个 SwiftUI 应用程序,它只有一个按钮。当我按下这个按钮时,我想调用 store 方法并保存一些 int 数字。例如数字 9。因此我创建了一个名为 write 的函数,如下所示:

 let myInt = 9

func write() {

let web3 = Web3.InfuraRinkebyWeb3(accessToken: "https://rinkeby.infura.io/v3/a146daf63d93490995823f0910f50118")

let walletAddress = EthereumAddress("0xc65943Fae5a554e7DCF916F8828a73E5f7b1bDCd")! // Your wallet address
let contractMethod = "store" // Contract method you want to write
let contractABI = contractABIString // Contract ABI
let contractAddress = EthereumAddress("0x2826C42354FE5B816c7E21AD9e3B395Ced512C0C")!
let abiVersion = 2 // Contract ABI version
let parameters = [myInt] as [AnyObject]
let extraData: Data = Data() // Extra data for contract method
let contract = web3.contract(contractABI, at: contractAddress, abiVersion: abiVersion)!
var options = TransactionOptions.defaultOptions
options.from = walletAddress
options.gasPrice = .automatic
options.gasLimit = .automatic

do {
contract.write(
contractMethod,
parameters: parameters,
extraData: extraData,
transactionOptions: options)

} catch {
print("error:", error)
}

不幸的是,当我运行这段代码时,什么也没有发生。我没有收到任何错误,但当我刷新契约(Contract)时,我看到数字 9 未通过。

我正在使用 web3swift 库,https://github.com/skywinder/web3swift/tree/master#send-erc-20-token .根据文档,它应该没问题,但它不工作,因此我非常感谢一些助手让它工作或一些示例项目我可以看看,因为我也找不到任何东西。

我找到了一些其他使用 JS 的项目,我看到那里的人使用他们的私钥,也许我也需要它,但由于它没有在文档中显示,我不确定如何使用它。

最佳答案

智能合约交互需要一些初始化步骤:

  1. 你的钱包
  2. keystore 管理器
  3. web3

假设您已经有了一个 Metamask 钱包。另外,您需要一个单独的文件,其中包含您要与之交互的智能合约的 ABI。它是一个数组,将它放在 Swift.String 中更容易。(我不会向您展示这一步)

   struct Wallet {
let address: String
let data: Data
let name: String
let isHD: Bool
}

class SmartContractInteraction {
var wallet: Wallet!
var keystoreManager: KeystoreManager!
var web3: web3!

init() {
wallet = initializeWallet()
keystoreManager = getKeyStoreManager()
web3 = initializeweb3()
}

private func initializeWallet() -> Wallet? {
let password = "PasswordMetamask"
let key = "AccountPrivateKey"
let formattedKey = key.trimmingCharacters(in: .whitespacesAndNewlines)
let dataKey = Data.fromHex(formattedKey)!
let name = "Account 1"
do {
let keystore = try EthereumKeystoreV3(privateKey: dataKey, password: password)!
let keyData = try JSONEncoder().encode(keystore.keystoreParams)
let address = keystore.addresses!.first!.address
return Wallet(address: address, data: keyData, name: name, isHD: false)
} catch {
print("wallet init failed: \(error)")
return nil
}
}

private func getKeyStoreManager() -> KeystoreManager {
let data = wallet.data
let keystoreManager: KeystoreManager
if wallet.isHD {
let keystore = BIP32Keystore(data)!
keystoreManager = KeystoreManager([keystore])
} else {
let keystore = EthereumKeystoreV3(data)!
keystoreManager = KeystoreManager([keystore])
}
return keystoreManager
}

private func initializeweb3() -> web3 {
let endpoint = "https://ropsten.infura.io/v3/....."
let web3 = web3swift.web3(provider: Web3HttpProvider(URL(string: endpoint)!)!)
web3.addKeystoreManager(keystoreManager)
return web3
}

func callSmartContract() {
let value: String = "1"
let walletAddress = EthereumAddress(wallet.address)!
let contractAddress = EthereumAddress("SmartContractAddress")!
let contractMethod = "store"
let contractABI = MyContractABI
let abiVersion = 2
let parameters = [9] as [AnyObject]
let extraData: Data = Data()
let contract = web3.contract(contractABI, at: contractAddress, abiVersion: abiVersion)!
let amount = Web3.Utils.parseToBigUInt(value, units: .wei)
var options = TransactionOptions.defaultOptions
options.value = amount
options.from = walletAddress
options.gasPrice = .automatic
options.gasLimit = .automatic
let tx = contract.write(
contractMethod,
parameters: parameters,
extraData: extraData,
transactionOptions: options)!
do {
let password = "MetamaskPassword"
let result = try tx.send(password: password)
print(result)
} catch {
print("Token Balance failed: \(error)")
}
}
}

这样应该可行,我认为在 smartContract 调用方法中传递 value/option.value 不是必需的,但由于我没有你的 ABI,我宁愿不从它对我的工作方式中删除任何东西。另外我不确定你传递的号码的类型。如果在没有 :) 的情况下可以正常工作,请随意编辑

关于swift - 如何从 Swift 应用程序与部署在区 block 链上的智能合约进行交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68596343/

55 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com