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; }
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 = ; }
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")); }
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); }
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); }
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); } } } } }
private static byte[] GetHash(string value) { return(Merkle.innerHash(Encoding.ASCII.GetBytes(value))); }