以太坊區塊鏈iOS開發之對web3swift庫的"addr"方法使用

NO IMAGE

由於web3swift庫並不完善,單元測試中缺少“addr”方法,而本人開發過程中又需要用到,即:將ENS域名轉成16進位制地址;於是特地寫了篇文章作為記錄,希望有同樣需求的同鞋能用上。

首先要引入web3swift庫,地址:https://github.com/BANKEX/web3swift

//MARK:將ENS域名轉成16進位制地址字串
func keccakHexStringFromENSString (inputName: String) -> String {
var node = ""
for _ in 0..<32 {
node  = "00"
}
let name = normalize(name: inputName)
if name.count > 0 {
//將字串用“.”分割成陣列並將陣列倒序
var labels = name.split(separator: ".")
labels.reverse()
//遞迴
for subLabels in labels {
let str = String(subLabels)
var labbelSha = str.sha3(.keccak256)
labbelSha = "0x"   node   labbelSha
let data = convertToData(labbelSha as AnyObject)
node = (data?.sha3(.keccak256).toHexString())!
print("0x"   node)
}
}
return infuratestResolver(encodeStr: "0x"   node)
}
//將某型別轉成Data
func convertToData(_ value: AnyObject) -> Data? {
switch value {
case let d as Data:
return d
case let d as String:
if d.hasHexPrefix() {
let hex = Data.fromHex(d)
if hex != nil {
return hex
}
}
let str = d.data(using: .utf8)
if str != nil {
return str
}
case let d as [UInt8]:
return Data(d)
case let d as EthereumAddress:
return d.addressData
case let d as [IntegerLiteralType]:
var bytesArray = [UInt8]()
for el in d {
guard el >= 0, el <= 255 else {return nil}
bytesArray.append(UInt8(el))
}
return Data(bytesArray)
default:
return nil
}
return nil
}
func normalize(name: String) -> String {
var lastName = name.trimmingCharacters(in: .whitespaces)
//判斷表情的正規表示式,並把表情替換為空
let pattern = "[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]"
lastName = lastName.pregReplace(pattern: pattern, with: "")
return lastName
}
//執行"addr"方法
func infuratestResolver(encodeStr: String) -> String {
let jsonString = "[{\"constant\":true,\"inputs\":[{\"name\":\"interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"contentTypes\",\"type\":\"uint256\"}],\"name\":\"ABI\",\"outputs\":[{\"name\":\"contentType\",\"type\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"x\",\"type\":\"bytes32\"},{\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"setPubkey\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"content\",\"outputs\":[{\"name\":\"ret\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"addr\",\"outputs\":[{\"name\":\"ret\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"contentType\",\"type\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"setABI\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"name\",\"outputs\":[{\"name\":\"ret\",\"type\":\"string\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"setContent\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"pubkey\",\"outputs\":[{\"name\":\"x\",\"type\":\"bytes32\"},{\"name\":\"y\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setAddr\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"inputs\":[{\"name\":\"ensAddr\",\"type\":\"address\"}],\"payable\":false,\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"address\"}],\"name\":\"AddrChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"ContentChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NameChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"contentType\",\"type\":\"uint256\"}],\"name\":\"ABIChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"x\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"PubkeyChanged\",\"type\":\"event\"}]"
do {
let web3 = Web3.InfuraMainnetWeb3()
let constractAddress = EthereumAddress("0x1da022710dF5002339274AaDEe8D58218e9D6AB5")
var options = Web3Options.defaultOptions()
options.to = constractAddress
options.from = constractAddress
let parametersCall = [encodeStr] as [AnyObject]
let contract = web3.contract(jsonString, at: constractAddress, abiVersion: 2)!
let transaction = contract.method("addr", parameters:parametersCall,  options: options)
guard let tokenNameRes = transaction?.call(options: options) else {return ""}
guard case .success(let result) = tokenNameRes else {return ""}
if result.isEmpty {
return ""
}else {
let dictValuesArray = [Any](result.values)
if dictValuesArray.count > 0 {
let addr: EthereumAddress = dictValuesArray[0] as! EthereumAddress
return addr.address
}else {
return ""
}
}
} catch {
XCTFail()
print(error)
return ""
}
}
//測試
func testABI() {
let ENSString = keccakHexStringFromENSString(inputName: "linktime.eth")
print(ENSString)
}