public OracleContractManager()
        {
            if (!EnsureKeyAcquired())
            {
                Message = "Could not import wallet key for oracle contract.";
                IsSetup = false;
                return;
            }

            //   var keypair = EnsureKeyPair();
            //   PrivateKey = keypair.PrivateKey;
            var contractCode = GetContractCode(/*keypair.PublicKey*/);

            ContractAddress = new Address(Merkle.innerHash(Encoding.ASCII.GetBytes(contractCode)), AddressType.Contract);

            if (!EnsureContractActive(contractCode))
            {
                Message = "Could not activate oracle contract.";
                IsSetup = false;
                return;
            }

            if (!EnsureInitialOutpoint())
            {
                Message = "Could not create initial outpoint.";
                IsSetup = false;
                return;
            }

            Message = "";
            IsSetup = true;
        }
예제 #2
0
        public void UpdateContractInfo()
        {
            var contractCode = _ContractView.Code;

            _Code = Encoding.ASCII.GetBytes(contractCode);

            _Hash = Merkle.innerHash(Encoding.ASCII.GetBytes(contractCode));

            _ContractView.Hash         = _Hash;
            _ContractView.CostPerBlock = ActiveContractSet.KalapasPerBlock(contractCode);

            //new GetIsContractActiveAction(_Hash).Publish().Result
            // var isActive = new GetIsContractActiveAction(_Hash).Publish();
            //_ContractView.IsActive = ;
        }
예제 #3
0
        public ActionResult Post()
        {
            Directory.CreateDirectory(Path.Combine("db", "contracts"));
            Directory.CreateDirectory(Path.Combine("db", "asset-metadata"));

            var contractCode = Utils.Dos2Unix(Request["contractCode"]);
            var contractHash = Merkle.innerHash(Encoding.ASCII.GetBytes(contractCode));
            var file         = $"{HttpServerUtility.UrlTokenEncode(contractHash)}";

            if (!System.IO.File.Exists(file))
            {
                System.IO.File.WriteAllText(Path.ChangeExtension(Path.Combine("db", "contracts", file), ".txt"), contractCode);
            }

            System.IO.File.WriteAllText(Path.ChangeExtension(Path.Combine("db", "asset-metadata", file), ".json"), JsonConvert.SerializeObject(new AssetMetadata()
            {
                name     = Request["assetName"],
                imageUrl = Request["assetImageURL"],
                version  = Request["assetMatadataVersion"]
            }));

            return(View("Index"));
        }
예제 #4
0
        bool ExtendMain(List <QueueAction> queuedActions, double totalWork, bool isGenesis = false)
        {
            if (_BlockChain.BlockStore.ContainsKey(_DbTx, _BkHash))
            {
                _BlockChain.BlockStore.SetLocation(_DbTx, _BkHash, LocationEnum.Main);
            }
            else
            {
                _BlockChain.BlockStore.Put(_DbTx, _BkHash, _Bk, LocationEnum.Main, totalWork);
            }

            _BlockChain.Timestamps.Push(_Bk.header.timestamp);

            if (_Bk.header.blockNumber % 2000 == 0)
            {
                _BlockChain.BlockNumberDifficulties.Add(_DbTx.Transaction, _Bk.header.blockNumber, _BkHash);
            }

            var blockUndoData = new BlockUndoData();

            var confirmedTxs = new HashDictionary <TransactionValidation.PointedTransaction>();

            //TODO: lock with mempool
            for (var txIdx = 0; txIdx < _Bk.transactions.Count(); txIdx++)
            {
                var tx     = _Bk.transactions[txIdx];
                var txHash = Merkle.transactionHasher.Invoke(tx);
                TransactionValidation.PointedTransaction ptx;

                if (!isGenesis)
                {
                    if ((txIdx == 0 && !IsCoinbaseTxValid(tx)) || (txIdx > 0 && IsCoinbaseTxValid(tx)))
                    {
                        if (txIdx == 0)
                        {
                            BlockChainTrace.Information("Invalid coinbase tx");
                        }
                        else
                        {
                            BlockChainTrace.Information($"Invalid tx ({txIdx})");
                        }

                        return(false);
                    }

                    if (!IsTransactionValid(tx, txHash, out ptx))
                    {
                        return(false);
                    }

                    confirmedTxs[txHash] = ptx;

                    foreach (var pInput in ptx.pInputs)
                    {
                        _BlockChain.UTXOStore.Remove(_DbTx, pInput.Item1);
                        BlockChainTrace.Information($"utxo spent, amount {pInput.Item2.spend.amount}", ptx);
                        //BlockChainTrace.Information($" of", pInput.Item1.txHash);
                        blockUndoData.RemovedUTXO.Add(new Tuple <Types.Outpoint, Types.Output>(pInput.Item1, pInput.Item2));
                    }
                }
                else
                {
                    ptx = TransactionValidation.toPointedTransaction(
                        tx,
                        ListModule.Empty <Types.Output>()
                        );
                }

                _BlockChain.BlockStore.TxStore.Put(_DbTx, txHash, tx, true);

                var contractExtendSacrifices = new HashDictionary <ulong>();
                var activationSacrifice      = 0UL;

                for (var outputIdx = 0; outputIdx < tx.outputs.Count(); outputIdx++)
                {
                    var output = tx.outputs[outputIdx];

                    if ([email protected])
                    {
                        if (!output.spend.asset.SequenceEqual(Tests.zhash))
                        {
                            continue;                             // not Zen
                        }
                        var contractSacrificeLock = (Types.OutputLock.ContractSacrificeLock)output.@lock;

                        if (contractSacrificeLock.IsHighVLock)
                        {
                            continue;                             // not current version
                        }
                        if (contractSacrificeLock.Item.lockData.Length > 0 && contractSacrificeLock.Item.lockData[0] != null && contractSacrificeLock.Item.lockData[0].Length > 0)
                        {
                            var contractKey = contractSacrificeLock.Item.lockData[0];                             // output-lock-level indicated contract

                            contractExtendSacrifices[contractKey] =
                                (contractExtendSacrifices.ContainsKey(contractKey) ? contractExtendSacrifices[contractKey] : 0) +
                                output.spend.amount;
                        }
                        else if (contractSacrificeLock.Item.lockData.Length == 0)
                        {
                            activationSacrifice += output.spend.amount;
                        }
                    }

                    //todo: fix  to exclude CSLocks&FLocks, instead of including by locktype
                    if ([email protected] || [email protected])
                    {
                        BlockChainTrace.Information($"new utxo, amount {output.spend.amount}", tx);
                        var outpoint = new Types.Outpoint(txHash, (uint)outputIdx);
                        _BlockChain.UTXOStore.Put(_DbTx, outpoint, output);
                        blockUndoData.AddedUTXO.Add(new Tuple <Types.Outpoint, Types.Output>(outpoint, output));
                    }
                }

                if (FSharpOption <Types.ExtendedContract> .get_IsSome(tx.contract) && !tx.contract.Value.IsHighVContract)
                {
                    var codeBytes    = ((Types.ExtendedContract.Contract)tx.contract.Value).Item.code;
                    var contractHash = Merkle.innerHash(codeBytes);
                    var contractCode = System.Text.Encoding.ASCII.GetString(codeBytes);

                    if (_BlockChain.ActiveContractSet.TryActivate(_DbTx, contractCode, activationSacrifice, contractHash, _Bk.header.blockNumber))
                    {
                        blockUndoData.ACSDeltas.Add(contractHash, new ACSUndoData());
                        ContractsTxsStore.Add(_DbTx.Transaction, contractHash, txHash);
                    }
                }

                foreach (var item in contractExtendSacrifices)
                {
                    var currentACSItem = _BlockChain.ActiveContractSet.Get(_DbTx, item.Key);

                    if (currentACSItem.Value != null)
                    {
                        if (_BlockChain.ActiveContractSet.TryExtend(_DbTx, item.Key, item.Value))
                        {
                            if (!blockUndoData.ACSDeltas.ContainsKey(item.Key))
                            {
                                blockUndoData.ACSDeltas.Add(item.Key, new ACSUndoData()
                                {
                                    LastBlock = currentACSItem.Value.LastBlock
                                });
                            }
                        }
                    }
                }
            }

            var expiringContracts = _BlockChain.ActiveContractSet.GetExpiringList(_DbTx, _Bk.header.blockNumber);

            foreach (var acsItem in expiringContracts)
            {
                if (!blockUndoData.ACSDeltas.ContainsKey(acsItem.Key))
                {
                    blockUndoData.ACSDeltas.Add(acsItem.Key, new ACSUndoData()
                    {
                        ACSItem = acsItem.Value
                    });
                }
            }

            if (!isGenesis)
            {
                _BlockChain.BlockStore.SetUndoData(_DbTx, _BkHash, blockUndoData);
            }

            _BlockChain.ActiveContractSet.DeactivateContracts(_DbTx, expiringContracts.Select(t => t.Key));

            ValidateACS();

            _BlockChain.ChainTip.Context(_DbTx).Value = _BkHash;
            //TODO: only update after commit
            _BlockChain.Tip = new Keyed <Types.Block>(_BkHash, _Bk);

            queuedActions.Add(new MessageAction(new BlockMessage(confirmedTxs, _Bk.header.blockNumber)));

            foreach (var item in confirmedTxs)
            {
                ConfirmedTxs[item.Key] = item.Value;
                UnconfirmedTxs.Remove(item.Key);
            }

            return(true);
        }
예제 #5
0
        public bool GetContractActivationTx(byte[] code, ulong zenAmount, out Types.Transaction signedTx, byte[] secureTokenHash = null)
        {
            ulong change;
            var   assets = new List <Asset>();

            var outputs = new List <Types.Output>();

            using (TransactionContext dbTx = _DBContext.GetTransactionContext())
            {
                if (!GetAssets(dbTx, Tests.zhash, zenAmount, out change, assets))
                {
                    signedTx = null;
                    return(false);
                }
                else if (change > 0)
                {
                    Key key;

                    if (_KeyStore.GetUnusedKey(dbTx, out key, true))
                    {
                        _Keys.Add(key);
                        dbTx.Commit();
                    }

                    outputs.Add(new Types.Output(key.Address.GetLock(), new Types.Spend(Tests.zhash, change)));
                }

                if (secureTokenHash != null)
                {
                    ulong secureTokenChange;
                    // var secureTokenAssets = new Assets();

                    if (!GetAssets(dbTx, secureTokenHash, 1, out secureTokenChange, assets))
                    {
                        signedTx = null;
                        return(false);
                    }
                    else if (secureTokenChange > 0)
                    {
                        Key key;

                        if (_KeyStore.GetUnusedKey(dbTx, out key, true))
                        {
                            _Keys.Add(key);
                            dbTx.Commit();
                        }

                        outputs.Add(new Types.Output(key.Address.GetLock(), new Types.Spend(secureTokenHash, secureTokenChange)));
                    }
                }
            }

            var output = new Types.Output(
                Types.OutputLock.NewContractSacrificeLock(
                    new Types.LockCore(0, ListModule.OfSeq(new byte[][] { }))
                    ),
                new Types.Spend(Tests.zhash, zenAmount)
                );

            outputs.Add(output);

            if (secureTokenHash != null)
            {
                outputs.Add(new Types.Output(Types.OutputLock.NewContractLock(Merkle.innerHash(code), new byte[] { }), new Types.Spend(secureTokenHash, 1)));
            }

            signedTx = TransactionValidation.signTx(new Types.Transaction(
                                                        0,
                                                        ListModule.OfSeq(assets.Select(t => t.Outpoint)),
                                                        ListModule.OfSeq(new List <byte[]>()),
                                                        ListModule.OfSeq(outputs),
                                                        new Microsoft.FSharp.Core.FSharpOption <Types.ExtendedContract>(
                                                            Types.ExtendedContract.NewContract(new Types.Contract(code, new byte[] { }, new byte[] { }))
                                                            )
                                                        ), ListModule.OfSeq(assets.Select(i => i.Key.Private)));

            return(true);
        }
예제 #6
0
        void HandleTx(TransactionValidation.PointedTransaction ptx)
        {
            //TODO: try simplify using hash from message
            var txHash = Merkle.transactionHasher.Invoke(TransactionValidation.unpoint(ptx));

            var activationSacrifice = 0UL;

            for (var i = 0; i < ptx.outputs.Length; i++)
            {
                var output = ptx.outputs[i];

                if ([email protected])
                {
                    if (!output.spend.asset.SequenceEqual(Tests.zhash))
                    {
                        continue;                         // not Zen
                    }
                    var contractSacrificeLock = (Types.OutputLock.ContractSacrificeLock)output.@lock;

                    if (contractSacrificeLock.IsHighVLock)
                    {
                        continue;                         // not current version
                    }
                    if (contractSacrificeLock.Item.lockData.Length == 0)
                    {
                        activationSacrifice += output.spend.amount;
                    }
                }

                //todo: fix  to exclude CSLocks&FLocks, instead of including by locktype
                if ([email protected] || [email protected])
                {
                    var outpoint = new Types.Outpoint(txHash, (uint)i);
                    _UtxoSet.Add(new Tuple <Types.Outpoint, Types.Output>(outpoint, output));
                }
            }

            if (FSharpOption <Types.ExtendedContract> .get_IsSome(ptx.contract) && !ptx.contract.Value.IsHighVContract)
            {
                var codeBytes    = ((Types.ExtendedContract.Contract)ptx.contract.Value).Item.code;
                var contractHash = Merkle.innerHash(codeBytes);
                var contractCode = System.Text.Encoding.ASCII.GetString(codeBytes);

                if (!_ActiveContracts.Contains(contractHash))
                {
                    if (activationSacrifice > ActiveContractSet.KalapasPerBlock(contractCode))
                    {
                        try
                        {
                            var compiledCodeOpt = ContractExamples.FStarExecution.compile(contractCode);

                            if (FSharpOption <byte[]> .get_IsSome(compiledCodeOpt))
                            {
                                _ActiveContracts.Add(contractHash);
                            }
                        }
                        catch (Exception e)
                        {
                            MinerTrace.Error("Could not compile contract " + Convert.ToBase64String(contractHash), e);
                        }
                    }
                }
            }
        }
예제 #7
0
 private static byte[] GetHash(string value)
 {
     return(Merkle.innerHash(Encoding.ASCII.GetBytes(value)));
 }