首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从Swift应用程序与部署在Blockchain上的智能契约进行交互

如何从Swift应用程序与部署在Blockchain上的智能契约进行交互
EN

Stack Overflow用户
提问于 2021-07-30 19:42:17
回答 1查看 642关注 0票数 3

这是我第一次使用智能合同,我的目标是创建一个移动应用程序,它可以通过调用方法来保存或检索数据来与其交互。因此,我使用Remix创建了一个非常简单的契约,我还部署在Rinkeby上。

代码语言:javascript
复制
contract Storage {

uint256 number;

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

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

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

代码语言:javascript
复制
 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)
    }

不幸的是,当我运行这段代码时,什么都没有发生。我没有收到任何错误,但是当我刷新合同时,我看到数字9没有被传递。

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-08 02:33:15

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

wallet

  • KeyStoreManager

  • web3

  1. Your

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

代码语言:javascript
复制
   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调用方法中传递值/option.value是不必要的,但是由于我没有您的ABI,所以我不想从它的工作方式中删除任何东西。另外,我也不确定你传递的号码的类型。如果没有:),可以随意编辑:)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68596343

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档