IOS钱包离线签名库开发指南

简介

当开发者需要使用IOS原生客户端进行 生成助记词助记词转私钥创建地址注册地址转账部署合约调用合约投票等操作时,维基链提供IOS的离线签名库供其使用。

源码和库

IOS原生钱包离线签名库基于Golang语言离线签名库编译而来,源码:

https://github.com/WaykiChain/wicc-wallet-utils-go

IOS原生钱包离线签名库下载地址:

https://github.com/WaykiChain/wicc-wallet-utils-go/releases/download/v2.0.0/ios-wiccwallet.framework.zip

使用方法

Bridge.h

//
//  Bridge.h
//  CommApp
//
//  Created by sorath on 2019/3/6.
//  Copyright © 2019 sorath. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Bridge : NSObject
//创建钱包、助记词
+ (NSString *)createNewWalletMnemonics;

//获取钱包地址和私钥
+ (NSArray *)getAddressAndPrivateKeyWithHelpString:(NSString *)helpStr;

//获取钱包哈希
+ (NSString *)getWalletHashFrom:(NSString *)codestring;

//检验钱包地址格式
+ (BOOL)addressIsAble:(NSString *)address;

//检查助记词列表

+(BOOL) checkMnemonicCode:(NSString*)words;

//打乱助记词数组词语顺序
//+ (NSArray *)getRamdomArrayWithArray:(NSArray *)array;

//获取激活hex
+ (NSString *)getActrivateHexWithHelpStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight ;

//获取转账wicc hex
+ (NSString *)getTransfetWICCHexWithHelpStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight srcRegId:(NSString *)srcRegId destAddr:(NSString *)destAddr transferValue:(double)value ;

//获取合约签名
+ (NSString *)getContractHexByContractStrWithHelpStr:(NSString *)helpStr privateKey:(NSString*)privateKey blockHeight:(double)validHeight regessID:(NSString *)regessID appid:(NSString *)appid contractStr:(NSString *)contractStr handleValue:(double)value fee:(double)fee;

///发布合约
+ (NSString *)contractPub:(NSString *)helpStr privateKey:(NSString*)privateKey blockHeight:(double)validHeight regessId:(NSString *)regessID contractStr:(NSString *)contractStr desc:(NSString *)desc fee:(double)fee;

///投票
+ (NSString *)nodeVote:(NSString *)helpStr blockHeight:(double)validHeight regessId:(NSString *)regessID beVotePubkey:(NSArray *)beVotePubkey beVoteAmounts:(NSArray *)beVoteAmounts fee:(double)fee;

///私钥登陆签名
+ (NSArray *)privateKeyToSingHex:(NSString *)privateKey randomStr:(NSString *)randomStr;

///检查私钥是否正确
+(BOOL) checkPrivateKey:(NSString*)private;

///通过私钥获取地址
+(NSString *)getAdressFromePrivateKey:(NSString*)privateKey;

///检查地址是否可用
+(BOOL)checkAddress:(NSString*)address;


///多币种合约签名
+ (NSString *)getUcoinContractHexWithHelpStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight srcRegId:(NSString *)srcRegId appid:(NSString *)appid coinSymbol:(NSString *)coinSymbol coinAmount:(double)coinAmount feeSymbol:(NSString *)feeSymbol contractHex:(NSString *)contractHex;

///多币种转账签名
+ (NSString *)getUcoinTXHexWithHelpStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight srcRegId:(NSString *)srcRegId destAddr:(NSString *)destAddr coinSymbol:(NSString *)coinSymbol transferValue:(double)value feeSymbol:(NSString *)feeSymbol memo:(NSString *)memo;

///发布资产签名
+ (NSString *)getAssetIssueStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight srcRegId:(NSString *)srcRegId assetSymbol:(NSString *)assetSymbol assetName:(NSString *)assetName assetTotal:(double)assetTotal feeSymbol:(NSString *)feeSymbol assetOwner:(NSString *)assetOwner minTable:(BOOL)minTable;

///更新资产签名
+ (NSString *)getAssetUpdateStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight srcRegId:(NSString *)srcRegId assetSymbol:(NSString *)assetSymbol assetName:(NSString *)assetName assetTotal:(double)assetTotal feeSymbol:(NSString *)feeSymbol assetOwner:(NSString *)assetOwner;
@end

NS_ASSUME_NONNULL_END

Bridge.m

//
//  Bridge.m
//  CommApp
//
//  Created by sorath on 2019/3/6.
//  Copyright © 2019 sorath. All rights reserved.
//

#import "Bridge.h"

#import "CommApp-Swift.h"
#import "Wiccwallet.framework/Headers/Wiccwallet.h"

@implementation Bridge
//NetType:   2测试网 1 主网
+ (long )getNetType{
    if ([OtherTools getWalletConfigure] == 1) {
        return 1;
    }
    return 2;
}


//根据助记词获取私钥和地址
+ (NSArray *)getAddressAndPrivateKeyWithHelpString:(NSString *)helpStr{
    NSError *error = [[NSError alloc] init];
    NSString *privateKey = WiccwalletGetPrivateKeyFromMnemonic(helpStr, [self getNetType],&error);
    NSString *address = WiccwalletGetAddressFromMnemonic(helpStr,[self getNetType],&error);

    return  @[address,privateKey];
}

+ (NSString *)createNewWalletMnemonics{
    NSString *mnemonics = WiccwalletGenerateMnemonics();
    return mnemonics;
}

+ (NSArray *)getWalletHelpCodesFrom:(NSString *)codestring
{
    NSArray *arr = [codestring componentsSeparatedByString:@" "];
    NSMutableArray *arr1 = [NSMutableArray arrayWithArray:arr];
    [arr1 removeObject:@" "];
    [arr1 removeObject:@""];
    return arr1;
}

+ (NSString *)getWalletHashFrom:(NSString *)codestring
{
    NSArray * helpcodes = [self getWalletHelpCodesFrom:codestring];
    int size = (int)helpcodes.count;
    int i = 0;
    NSMutableString* strWords = [[NSMutableString alloc]init];
    for(id word in helpcodes) {
        [strWords appendString:word];
        if(i != size - 1) {
            [strWords appendString:@" "];
        }
        i++;
    }
    return  strWords.sha512String;
}

+ (NSString *)getWaletHelpStringWithCodes:(NSArray *)helpcodes{
    // 产生钱包字符串
    int size = (int)helpcodes.count;
    int i = 0;
    NSMutableString* strWords = [[NSMutableString alloc]init];
    for(id word in helpcodes) {
        [strWords appendString:word];
        if(i != size - 1) {
            [strWords appendString:@" "];
        }
        i++;
    }
    return  strWords;
}

+ (BOOL)addressIsAble:(NSString *)address{
    return YES;
}

//检验助记词
+(BOOL) checkMnemonicCode:(NSString*)words{
    NSError *error = [[NSError alloc] init];
    NSString *address = WiccwalletGetAddressFromMnemonic(words, [self getNetType],&error);
    if (address){
        return YES;
    }
    return NO;
}
//检验私钥
+(BOOL) checkPrivateKey:(NSString*)private{
    BOOL isTrue = true;
    NSError *error = [[NSError alloc] init];
    BOOL isRight  = WiccwalletCheckPrivateKey(private, [self getNetType], &isTrue, &error);
    NSLog(@"%d",isTrue);
    return isRight;
}



//获取激活hex
+ (NSString *)getActrivateHexWithHelpStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight{
    NSError *error = [[NSError alloc] init];
    NSString *private = @"";
    if ([privateKey isEqualToString:@""]){
        private = WiccwalletGetPrivateKeyFromMnemonic(helpStr, [self getNetType],&error);
    }else{
        private = privateKey;
    }
    NSInteger fee = fees*100000000+(arc4random() % 100);
    WiccwalletRegisterAccountTxParam * para = [[WiccwalletRegisterAccountTxParam alloc] init];
    para.fees = fee;
    para.validHeight = validHeight;
    NSString *hex =  WiccwalletSignRegisterAccountTx(private,para,&error);
    return hex;
}

//获取转账wicc hex
+ (NSString *)getTransfetWICCHexWithHelpStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight srcRegId:(NSString *)srcRegId destAddr:(NSString *)destAddr transferValue:(double)value {
    NSError *error = [[NSError alloc] init];
    NSString *private = @"";
    if ([privateKey isEqualToString:@""]){
        private = WiccwalletGetPrivateKeyFromMnemonic(helpStr, [self getNetType],&error);
    }else{
        private = privateKey;
    }
    UInt64 fee = fees*100000000+(NSInteger)(arc4random() % 100);
    UInt64 transferValue = (NSInteger)(value*100000000);
    NSError *error2 = [[NSError alloc] init];
    WiccwalletCommonTxParam * para = [[WiccwalletCommonTxParam alloc] init];
    para.fees = fee;
    para.validHeight = validHeight;
    para.values = transferValue;
    para.srcRegId = srcRegId;
    para.destAddr = destAddr;
    para.pubKey = WiccwalletGetPubKeyFromPrivateKey(private, &error2);
    NSString *hex =  WiccwalletSignCommonTx(private,para,&error);

    return hex;
}



///多币种转账签名
+ (NSString *)getUcoinTXHexWithHelpStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight srcRegId:(NSString *)srcRegId destAddr:(NSString *)destAddr coinSymbol:(NSString *)coinSymbol transferValue:(double)value feeSymbol:(NSString *)feeSymbol memo:(NSString *)memo{
    NSError *error = [[NSError alloc] init];
    NSString *private = @"";
    if ([privateKey isEqualToString:@""]){
        private = WiccwalletGetPrivateKeyFromMnemonic(helpStr, [self getNetType],&error);
    }else{
        private = privateKey;
    }
    UInt64 fee = fees*100000000+(NSInteger)(arc4random() % 100);
    UInt64 transferValue = (NSInteger)(value*100000000);
    NSError *error2 = [[NSError alloc] init];
    WiccwalletUCoinTransferTxParam * para = [[WiccwalletUCoinTransferTxParam alloc] init];

    WiccwalletDestArr * destArr = [[WiccwalletDestArr alloc] init];
    WiccwalletDest * dest = [[WiccwalletDest alloc] init];
    dest.coinSymbol = coinSymbol;
    dest.coinAmount = transferValue;
    dest.destAddr = destAddr;
    [destArr add:dest];

    para.fees = fee;
    para.validHeight = validHeight;
    para.srcRegId = srcRegId;
    para.dests = destArr;
    para.feeSymbol = feeSymbol;
    para.memo = memo;
    para.pubKey = WiccwalletGetPubKeyFromPrivateKey(private, &error2);
    NSString *hex =  WiccwalletSignUCoinTransferTx(private,para,&error);

    return hex;
}


///多币种合约签名
+ (NSString *)getUcoinContractHexWithHelpStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight srcRegId:(NSString *)srcRegId appid:(NSString *)appid coinSymbol:(NSString *)coinSymbol coinAmount:(double)coinAmount feeSymbol:(NSString *)feeSymbol contractHex:(NSString *)contractHex{
    NSError *error = [[NSError alloc] init];
    NSString *private = @"";
    if ([privateKey isEqualToString:@""]){
        private = WiccwalletGetPrivateKeyFromMnemonic(helpStr, [self getNetType],&error);
    }else{
        private = privateKey;
    }
    UInt64 fee = fees*100000000+(NSInteger)(arc4random() % 100);
    UInt64 transferValue = (NSInteger)(coinAmount*100000000);
    NSError *error2 = [[NSError alloc] init];
    WiccwalletUCoinContractTxParam * para = [[WiccwalletUCoinContractTxParam alloc] init];
    para.fees = fee;
    para.validHeight = validHeight;
    para.srcRegId = srcRegId;
    para.appId = appid;
    para.feeSymbol = feeSymbol;
    para.coinSymbol = coinSymbol;
    para.coinAmount = transferValue;
    para.contractHex = contractHex;
    para.pubKey = WiccwalletGetPubKeyFromPrivateKey(private, &error2);
    NSString *hex =  WiccwalletSignUCoinCallContractTx(private,para,&error);

    return hex;
}



//获取合约签名
+ (NSString *)getContractHexByContractStrWithHelpStr:(NSString *)helpStr privateKey:(NSString*)privateKey blockHeight:(double)validHeight regessID:(NSString *)regessID appid:(NSString *)appid contractStr:(NSString *)contractStr handleValue:(double)value fee:(double)fee{
    NSError *error = [[NSError alloc] init];
    NSString *private = @"";
    if ([privateKey isEqualToString:@""]){
        private = WiccwalletGetPrivateKeyFromMnemonic(helpStr, [self getNetType],&error);
    }else{
        private = privateKey;
    }

    UInt64 exFee = fee    * 100000000 + (NSInteger)(arc4random() % 100);
    UInt64 exchangeValue = (NSInteger)(value);
    WiccwalletCallContractTxParam* para = [[WiccwalletCallContractTxParam alloc] init];
    para.fees = exFee;
    para.validHeight = validHeight;
    para.srcRegId = regessID;
    para.values = exchangeValue;
    para.appId = appid;
    para.pubKey = WiccwalletGetPubKeyFromPrivateKey(private, &error);
    para.contractHex = contractStr;
    NSString *hex =  WiccwalletSignCallContractTx(private,para,&error);
    NSDictionary * errorMSg = error.userInfo;
    NSString *msg = errorMSg[@"NSLocalizedDescription"];
    if (msg){
        return [NSString stringWithFormat:@"error-%@",msg];
    }
    return hex;
}

//发布合约
+ (NSString *)contractPub:(NSString *)helpStr privateKey:(NSString*)privateKey blockHeight:(double)validHeight regessId:(NSString *)regessID contractStr:(NSString *)contractStr desc:(NSString *)desc fee:(double)fee{
    NSError *error = [[NSError alloc] init];
    NSString *private = @"";
    if ([privateKey isEqualToString:@""]){
        private = WiccwalletGetPrivateKeyFromMnemonic(helpStr, [self getNetType],&error);
    }else{
        private = privateKey;
    }
    UInt64 exFee = fee    * 100000000 + (NSInteger)(arc4random() % 100);
    WiccwalletRegisterContractTxParam* para = [[WiccwalletRegisterContractTxParam alloc] init];
    para.fees = exFee;
    para.validHeight = validHeight;
    para.srcRegId = regessID;
    NSData * data = [contractStr dataUsingEncoding:NSUTF8StringEncoding];

    para.script = data;
    para.description = desc;

    NSString *hex =  WiccwalletSignRegisterContractTx(private,para,&error);
    NSDictionary * errorMSg = error.userInfo;
    NSString *msg = errorMSg[@"NSLocalizedDescription"];
    if (msg){
        return [NSString stringWithFormat:@"error-%@",msg];
    }
    return hex;
}


//节点投票
+ (NSString *)nodeVote:(NSString *)helpStr blockHeight:(double)validHeight regessId:(NSString *)regessID beVotePubkey:(NSArray *)beVotePubkey beVoteAmounts:(NSArray *)beVoteAmounts fee:(double)fee{
    NSError *error = [[NSError alloc] init];
    NSString *privateKey = WiccwalletGetPrivateKeyFromMnemonic(helpStr,[self getNetType],&error);
    UInt64 exFee = fee * 100000000 + (NSInteger)(arc4random() % 100);
    WiccwalletDelegateTxParam * para = [[WiccwalletDelegateTxParam alloc] init];
    para.validHeight = validHeight;
    para.srcRegId = regessID;
    para.fees = exFee;

    WiccwalletOperVoteFunds * voteFounds = [[WiccwalletOperVoteFunds alloc] init];
    for(int i = 0 ; i < beVotePubkey.count ; i++){
        WiccwalletOperVoteFund * found = [[WiccwalletOperVoteFund alloc] init];
        UInt64 amount = [beVoteAmounts[i] doubleValue];
        found.pubKey = [self convertHexStrToData:beVotePubkey[i]];
        found.voteValue = amount;
        [voteFounds add:found];

    }
    para.votes = voteFounds;
    NSString *hex =  WiccwalletSignDelegateTx(privateKey, para , &error);
    NSDictionary * errorMSg = error.userInfo;
    NSString *msg = errorMSg[@"NSLocalizedDescription"];
    if (msg){
        return [NSString stringWithFormat:@"error-%@",msg];
    }
    return hex;
}

+ (BOOL)checkAddress:(NSString *)address{
    BOOL b = false;
    NSError *error = [[NSError alloc] init];
    BOOL a = WiccwalletCheckWalletAddress(address, [self getNetType], &b, &error);
    return a;
}

// 16进制字符串 -> 2进制数据
+ (NSData *)convertHexStrToData:(NSString *)str {
    if (!str || [str length] == 0) {
        return nil;
    }

    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
    NSRange range;
    if ([str length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [str length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [str substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];

        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];

        range.location += range.length;
        range.length = 2;
    }
    return hexData;
}


+(NSArray *)privateKeyToSingHex:(NSString *)privateKey randomStr:(nonnull NSString *)randomStr{
    NSError *error = [[NSError alloc] init];
    WiccwalletSignMessageParam *msgParam = WiccwalletSignMessage(privateKey, randomStr, &error);
    NSString *pubKey = msgParam.publicKey;
    NSString *signMsg = msgParam.signMessage;
    NSArray *arr = [NSArray arrayWithObjects:pubKey,signMsg, nil];
    return arr;
}

///通过私钥获取地址
+(NSString *)getAdressFromePrivateKey:(NSString*)privateKey{
    NSString *address = WiccwalletGetAddressFromPrivateKey(privateKey, [self getNetType]);
    return address;
}



///发布资产签名
+ (NSString *)getAssetIssueStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight srcRegId:(NSString *)srcRegId assetSymbol:(NSString *)assetSymbol assetName:(NSString *)assetName assetTotal:(double)assetTotal feeSymbol:(NSString *)feeSymbol assetOwner:(NSString *)assetOwner minTable:(BOOL)minTable{
    NSError *error = [[NSError alloc] init];
    NSString *private = @"";
    if ([privateKey isEqualToString:@""]){
        private = WiccwalletGetPrivateKeyFromMnemonic(helpStr, [self getNetType],&error);
    }else{
        private = privateKey;
    }
    UInt64 fee = fees*100000000+(NSInteger)(arc4random() % 100);
    UInt64 transferValue = (NSInteger)(assetTotal*100000000);
    WiccwalletAssetIssueTxParam * para = [[WiccwalletAssetIssueTxParam alloc] init];
    para.fees = fee;
    para.validHeight = validHeight;
    para.srcRegId = srcRegId;
    para.feeSymbol = feeSymbol;

    para.assetSymbol = assetSymbol;
    para.assetName = assetName;
    para.assetTotal = transferValue;
    para.assetOwner = assetOwner;
    para.minTable = minTable;
    NSString *hex =  WiccwalletSignAssetCreateTx(private,para,&error);

    return hex;
}

///更新资产签名
+ (NSString *)getAssetUpdateStr:(NSString *)helpStr privateKey:(NSString*)privateKey Fees:(double)fees validHeight:(double)validHeight srcRegId:(NSString *)srcRegId assetSymbol:(NSString *)assetSymbol assetName:(NSString *)assetName assetTotal:(double)assetTotal feeSymbol:(NSString *)feeSymbol assetOwner:(NSString *)assetOwner updateType:(NSInteger)updateType{
    NSError *error = [[NSError alloc] init];
    NSString *private = @"";
    if ([privateKey isEqualToString:@""]){
        private = WiccwalletGetPrivateKeyFromMnemonic(helpStr, [self getNetType],&error);
    }else{
        private = privateKey;
    }
    UInt64 fee = fees*100000000+(NSInteger)(arc4random() % 100);
    UInt64 transferValue = (NSInteger)(assetTotal*100000000);
    WiccwalletAssetUpdateTxParam * para = [[WiccwalletAssetUpdateTxParam alloc] init];
    para.fees = fee;
    para.validHeight = validHeight;
    para.srcRegId = srcRegId;
    para.feeSymbol = feeSymbol;

    para.updateType = updateType;
    para.assetSymbol = assetSymbol;
    para.assetName = assetName;
    para.assetTotal = transferValue;
    para.assetOwner = assetOwner;

    NSString *hex =  WiccwalletSignAssetUpdateTx(private,para,&error);

    return hex;
}





@end