廢話
因為專案業務原因,需要在新的專案中部署以太坊的智慧合約,關於這方面安卓方面貌似走在了前面。 web3j 的存在實在是喜人,而 iOS版本也是有的,功能貌似沒有那麼強大,對付平常的區塊鏈互動是足夠的了。但是iOS這個他沒有仔細的說明,我研究了一下其實部署起來挺簡單. 年紀大了搞過的東西很容易忘記,於是在這裡記錄一下.一來自己以後也可以回顧,二來為有需要的人略盡綿薄之力
使用 web3swift 部署以太坊智慧合約
1.配置服務
a. IP地址
配置以太坊的伺服器地址:
我這裡是本地IP地址
struct Api {
static let host = "http://192.168.6.66:6666"
static func map(path: String) -> String {
return host + path
}
static var chainUrl: String {
return map(path: "")
}
}
複製程式碼
b. abiString
部署合約會需要
public let abiString = "[{"constant":true,"inputs":[],"name":"getFlagData","outputs":[{"name":"data","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"data","type":"string"}],"name":"setFlagData","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]"
複製程式碼
c. byteCode
這個是一串很長的東西,合約生產的。沒有的記得找寫合約的要.
我這裡的例子:
public let BINARY = "606060409081526003805460a060020a61ffff021916905560006004558051908101604052600981527f4c696e67546f6b656e0000000000000000000000000000000000000000000000602082015260059080516100619291602001906100cf565b5060408051908101604052600481527f4c494e4700000000000000000000000000000000000000000000000000000000602082015260069080516100a99291602001906100cf565b50601260075560038054600160a060020a03191633600160a060020a031617905561016a565b82805460018160011615610100020316600290049若干省略號
複製程式碼
d. 整合 pod
pod `web3swift`, `~> 0.8.0`
複製程式碼
2.部署前奏
a. 建立賬戶,web3swift 的示例中有,同學可以仔細研究研究,我這裡就簡單過。
上程式碼:
class YYGKey {
var key_password = "BANKEXFOUNDATION"
var storeManager: KeystoreManager? {
return keyStoreManager()
}
var keyAddress: EthereumKeystoreV3? {
return addressManage()
}
convenience init(password: String) {
self.init()
self.key_password = password
}
func addressManage() -> EthereumKeystoreV3? {
guard let userDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else { return nil }
let storeManager = KeystoreManager.managerForPath(userDir + "/keystore")
if let manage = storeManager, let address = manage.addresses {
return address.isEmpty ? creatAddress(dir: userDir) : getAddress(manage: manage)
}
return nil
}
func creatAddress(dir: String) -> EthereumKeystoreV3? {
let ks = try! EthereumKeystoreV3(password: "BANKEXFOUNDATION")
if let ks_ = ks {
let keydata = try! JSONEncoder().encode(ks_.keystoreParams)
FileManager.default.createFile(atPath: dir + "/keystore"+"/key.json", contents: keydata, attributes: nil)
}
return ks
}
func getAddress(manage: KeystoreManager) -> EthereumKeystoreV3? {
if let address = manage.addresses, let first = address.first {
return manage.walletForAddress(first) as? EthereumKeystoreV3
}
return nil
}
func keyStoreManager() -> KeystoreManager? {
guard let userDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else { return nil }
return KeystoreManager.managerForPath(userDir + "/keystore")
}
}
複製程式碼
b. 連線到部署的伺服器
class YYG {
var chain: web3? {
guard let url = URL(string: Api.chainUrl), let web = Web3.new(url) else { return nil }
return web
}
static let yyg = YYG()
private init() { }
}
複製程式碼
3.開始部署
需要的資料
- EthereumKeystoreV3
- EthereumAddress
- web3
- byteCode
- web3contract
- Web3Options
- TransactionIntermediate
- KeystoreManager
上程式碼:
struct YYGOperate {
typealias result = Result<[String : String], Web3Error>
typealias res = [String : String]
func contractsResult(message: @escaping (Bool,res?) -> Void) {
if let resul = smartContracts() {
switch resul {
case .success(let res):
DispatchQueue.main.async {
message(true, res)
}
case .failure(let error):
message(false, nil)
print(error)
}
} else {
message(false, nil)
}
}
private func smartContracts() -> result? {
guard let manage = YYGKey().addressManage(),let addresss = manage.addresses,let address = addresss.first, let chain = YYG.yyg.chain else { return nil }
chain.provider.network = nil
chain.addKeystoreManager(YYGKey().keyStoreManager())
guard let contract = chain.contract(abiString, at: nil, abiVersion: 2), let byteCode = Data.fromHex(BINARY) else { return nil }
var options = Web3Options.defaultOptions()
options.from = address
options.gasLimit = BigUInt(3000000)
let inter = contract.deploy(bytecode: byteCode, options: options)
guard let intermediate = inter else { return nil }
return intermediate.send(password: "BANKEXFOUNDATION", options: options)
}
}
複製程式碼
3.執行
YYGOperate().contractsResult { state, res in
if state { printLogDebug(res) }
}
複製程式碼
結果:
Transaction
Nonce: 10
Gas price: 5000000000
Gas limit: 1111340
To: 0x
Value: 0
Data: 0x606060409081526003805460a060020a61ffff02191690556090810183818151815260200191508051906020019080838360005b8381101561017657808201518382015260200161015e565b50、5260200160405180910390a35050505050565b6000828201610acc82fd76404b5c55184a2e555312d3353bcb43e75666dd36d0af562b0c220029a165627a7a72305820f3efa245dad6ee48cc6d771a54067fb6e3b17b0caba5ecd4eed13aca2b1c00960029
v: 28
r: 79879464740714101996923170089344479265591202785750775462035438111705924396692
s: 39143622105442894879914151031821436277241889279036648521816051027427579390397
Intrinsic chainID: nil
Infered chainID: nil
sender: Optional("0x9E40Fb081777c232aBafc256165772572c057F95")
hash: Optional("0xcc16c3a245e4fd27b85e53b8cb6d0ac64028b60e61ca3de938e896e95202bde3")
複製程式碼
授人以魚不如授人以漁
學習資料