public static byte[] create(byte[] invoker, byte[][] owners, byte[] theOperator, byte[] nonce)
        {
            BasicMethods.assert(Runtime.CheckWitness(invoker), "CheckWitness failed");
            BasicMethods.assert(BasicMethods._isLegalAddresses(owners), "owners addresses are not byte20");
            BasicMethods.assert(BasicMethods._isLegalAddress(theOperator), "the operator is not byte20");
            //TODO: no need to check the nonce byte[] length

            _whenNotPaused();

            BasicMethods.assert(BasicMethods._isLegalAddress(theOperator), "New operator is address zero");
            byte[] SelfContractHash = ExecutionEngine.ExecutingScriptHash;
            byte[] concatRes        = SelfContractHash.Concat(invoker).Concat(nonce);
            byte[] walletId         = SmartContract.Sha256(concatRes);
            BasicMethods.assert(getWallet(walletId).theOperator == null, "Occupied wallet id");
            Wallet w = new Wallet();

            BasicMethods.assert(BasicMethods._isLegalAddresses(owners), "owners contains illegal address");
            w.owners      = owners;
            w.theOperator = theOperator;
            BigInteger walletNum = Storage.Get(Storage.CurrentContext, WalletNum).AsBigInteger();

            Storage.Put(Storage.CurrentContext, WalletNum, (walletNum + 1).AsByteArray());
            Storage.Put(Storage.CurrentContext, WalletsPrefix.Concat(walletId), Helper.Serialize(w));
            CreateWallet(walletId, owners, theOperator);
            return(walletId);
        }