Esempio n. 1
0
    public bool IsSignedBy(string user)
    {
        var pubkey = PubKey.FromBase58(user);

        /* Console.WriteLine(pubkey.Address);
         * Console.WriteLine("data length: {0}",data.Length);
         * Console.WriteLine("signature length: {0}", signed.Length); */
        return(pubkey.Verify(Hex.Parse("03" + data), Hex.Parse(signature)));
    }
Esempio n. 2
0
        public bool TryAuthenticate(AuthHeaders headers, out string error)
        {
            error = null;

            if (string.IsNullOrEmpty(headers?.User))
            {
                error = $"The X-TZKT-USER header is required";
                return(false);
            }

            if (headers.Nonce == null)
            {
                error = $"The X-TZKT-NONCE header is required";
                return(false);
            }

            if (string.IsNullOrEmpty(headers.Signature))
            {
                error = $"The X-TZKT-SIGNATURE header is required";
                return(false);
            }

            if (!Config.Credentials.TryGetValue(headers.User, out var pubKey))
            {
                error = $"User {headers.User} doesn't exist";
                return(false);
            }

            var nonce     = (long)headers.Nonce;
            var nonceTime = DateTime.UnixEpoch.AddMilliseconds(nonce);

            if (nonceTime < DateTime.UtcNow.AddSeconds(-Config.NonceLifetime))
            {
                error = $"Nonce too old. Server time: {DateTime.UtcNow}, nonce: {nonceTime}";
                return(false);
            }

            if (nonce <= Nonces[headers.User])
            {
                error = $"Nonce {nonce} has already used";
                return(false);
            }

            var key = PubKey.FromBase58(pubKey);

            if (!key.Verify($"{headers.Nonce}", headers.Signature))
            {
                error = $"Invalid signature";
                return(false);
            }

            Nonces[headers.User] = nonce;
            return(true);
        }
Esempio n. 3
0
        async Task <List <Account> > BootstrapAccounts(Protocol protocol, JToken parameters)
        {
            var bootstrapAccounts = parameters["bootstrap_accounts"]?
                                    .Select(x => (x[0].Value <string>(), x[1].Value <long>()))
                                    .ToList() ?? new(0);

            var bootstrapContracts = parameters["bootstrap_contracts"]?
                                     .Select(x =>
                                             (
                                                 x["amount"].Value <long>(),
                                                 x["delegate"]?.Value <string>() ?? null,
                                                 x["script"]["code"].ToString(),
                                                 x["script"]["storage"].ToString())
                                             )
                                     .ToList() ?? new(0);

            var accounts = new List <Account>(bootstrapAccounts.Count + bootstrapContracts.Count);

            #region allocate null-address
            var nullAddress = (User)await Cache.Accounts.GetAsync(NullAddress.Address);

            if (nullAddress.Id != NullAddress.Id)
            {
                throw new Exception("Failed to allocate null-address");
            }
            #endregion

            #region bootstrap delegates
            foreach (var(pubKey, balance) in bootstrapAccounts.Where(x => x.Item1[0] != 't'))
            {
                var baker = new Data.Models.Delegate
                {
                    Id                = Cache.AppState.NextAccountId(),
                    Address           = PubKey.FromBase58(pubKey).Address,
                    Balance           = balance,
                    StakingBalance    = balance,
                    Counter           = 0,
                    PublicKey         = pubKey,
                    FirstLevel        = 1,
                    LastLevel         = 1,
                    ActivationLevel   = 1,
                    DeactivationLevel = GracePeriod.Init(2, protocol),
                    Staked            = true,
                    Revealed          = true,
                    Type              = AccountType.Delegate
                };
                Cache.Accounts.Add(baker);
                accounts.Add(baker);
            }
            #endregion

            #region bootstrap users
            foreach (var(pkh, balance) in bootstrapAccounts.Where(x => x.Item1[0] == 't'))
            {
                var user = new User
                {
                    Id         = Cache.AppState.NextAccountId(),
                    Address    = pkh,
                    Balance    = balance,
                    Counter    = 0,
                    FirstLevel = 1,
                    LastLevel  = 1,
                    Type       = AccountType.User
                };
                Cache.Accounts.Add(user);
                accounts.Add(user);
            }
            #endregion

            #region bootstrap contracts
            var index = 0;
            foreach (var(balance, delegatePkh, codeStr, storageStr) in bootstrapContracts)
            {
                #region contract
                var delegat = Cache.Accounts.GetDelegate(delegatePkh);
                var manager = nullAddress;

                var contract = new Contract
                {
                    Id              = Cache.AppState.NextAccountId(),
                    Address         = OriginationNonce.GetContractAddress(index++),
                    Balance         = balance,
                    Counter         = 0,
                    FirstLevel      = 1,
                    LastLevel       = 1,
                    Spendable       = false,
                    DelegationLevel = delegat == null ? null : 1,
                    Delegate        = delegat,
                    Manager         = manager,
                    Staked          = delegat != null,
                    Type            = AccountType.Contract,
                    Kind            = ContractKind.SmartContract,
                };

                manager.ContractsCount++;
                if (delegat != null)
                {
                    delegat.DelegatorsCount++;
                    delegat.StakingBalance += contract.Balance;
                }

                Cache.Accounts.Add(contract);
                accounts.Add(contract);
                #endregion

                #region script
                var code           = Micheline.FromJson(codeStr) as MichelineArray;
                var micheParameter = code.First(x => x is MichelinePrim p && p.Prim == PrimType.parameter);
                var micheStorage   = code.First(x => x is MichelinePrim p && p.Prim == PrimType.storage);
                var micheCode      = code.First(x => x is MichelinePrim p && p.Prim == PrimType.code);
                var micheViews     = code.Where(x => x is MichelinePrim p && p.Prim == PrimType.view);
                var script         = new Script
                {
                    Id              = Cache.AppState.NextScriptId(),
                    Level           = 1,
                    ContractId      = contract.Id,
                    ParameterSchema = micheParameter.ToBytes(),
                    StorageSchema   = micheStorage.ToBytes(),
                    CodeSchema      = micheCode.ToBytes(),
                    Views           = micheViews.Any()
                        ? micheViews.Select(x => x.ToBytes()).ToArray()
                        : null,
                    Current = true
                };

                var viewsBytes = script.Views?
                                 .OrderBy(x => x, new BytesComparer())
                                 .SelectMany(x => x)
                                 .ToArray()
                                 ?? Array.Empty <byte>();
                var typeSchema = script.ParameterSchema.Concat(script.StorageSchema).Concat(viewsBytes);
                var fullSchema = typeSchema.Concat(script.CodeSchema);
                contract.TypeHash = script.TypeHash = Script.GetHash(typeSchema);
                contract.CodeHash = script.CodeHash = Script.GetHash(fullSchema);

                if (script.Schema.IsFA1())
                {
                    if (script.Schema.IsFA12())
                    {
                        contract.Tags |= ContractTags.FA12;
                    }

                    contract.Tags |= ContractTags.FA1;
                    contract.Kind  = ContractKind.Asset;
                }
                if (script.Schema.IsFA2())
                {
                    contract.Tags |= ContractTags.FA2;
                    contract.Kind  = ContractKind.Asset;
                }

                Db.Scripts.Add(script);
                Cache.Schemas.Add(contract, script.Schema);
                #endregion

                #region storage
                var storageValue = Micheline.FromJson(storageStr);
                var storage      = new Storage
                {
                    Id         = Cache.AppState.NextStorageId(),
                    Level      = 1,
                    ContractId = contract.Id,
                    RawValue   = script.Schema.OptimizeStorage(storageValue, false).ToBytes(),
                    JsonValue  = script.Schema.HumanizeStorage(storageValue),
                    Current    = true
                };

                Db.Storages.Add(storage);
                Cache.Storages.Add(contract, storage);
                #endregion
            }
            #endregion

            Db.Accounts.AddRange(accounts);

            #region migration ops
            var block = Cache.Blocks.Current();

            block.Operations |= Operations.Migrations;
            if (accounts.Any(x => x.Type == AccountType.Contract))
            {
                block.Events |= BlockEvents.SmartContracts;
            }

            foreach (var account in accounts)
            {
                var migration = new MigrationOperation
                {
                    Id            = Cache.AppState.NextOperationId(),
                    Block         = block,
                    Level         = block.Level,
                    Timestamp     = block.Timestamp,
                    Account       = account,
                    Kind          = MigrationKind.Bootstrap,
                    BalanceChange = account.Balance,
                };

                if (account is Contract contract)
                {
                    var script = Db.ChangeTracker.Entries()
                                 .First(x => x.Entity is Script s && s.ContractId == contract.Id).Entity as Script;
                    var storage = await Cache.Storages.GetAsync(contract);

                    script.MigrationId  = migration.Id;
                    storage.MigrationId = migration.Id;

                    migration.Script  = script;
                    migration.Storage = storage;
                }

                Db.MigrationOps.Add(migration);
                account.MigrationsCount++;
            }

            var state = Cache.AppState.Get();
            state.MigrationOpsCount += accounts.Count;
            #endregion

            #region statistics
            var stats = await Cache.Statistics.GetAsync(1);

            stats.TotalBootstrapped = accounts.Sum(x => x.Balance);
            stats.TotalVested       = accounts.Where(x => x.Type == AccountType.Contract).Sum(x => x.Balance);
            #endregion

            return(accounts);
        }