Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add VRF random number to neo #2476

Closed
wants to merge 12 commits into from
373 changes: 373 additions & 0 deletions src/neo/Cryptography/VRF.cs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/neo/NeoSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ public NeoSystem(ProtocolSettings settings, string storageEngine = null, string
MerkleRoot = UInt256.Zero,
Timestamp = (new DateTime(2016, 7, 15, 15, 8, 21, DateTimeKind.Utc)).ToTimestampMS(),
Index = 0,
Nonce = 2083236893, // nonce from the Bitcoin genesis block.
PrimaryIndex = 0,
NextConsensus = Contract.GetBFTAddress(settings.StandbyValidators),
Witness = new Witness
Expand Down
5 changes: 5 additions & 0 deletions src/neo/Network/P2P/Payloads/Block.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public sealed class Block : IEquatable<Block>, IInventory
/// </summary>
public uint Index => Header.Index;

/// <summary>
/// The random number of the block from VRF.
/// </summary>
public uint Nonce => Header.Nonce;

/// <summary>
/// The primary index of the consensus node that generated this block.
/// </summary>
Expand Down
15 changes: 15 additions & 0 deletions src/neo/Network/P2P/Payloads/Header.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ public sealed class Header : IEquatable<Header>, IVerifiable
private UInt256 merkleRoot;
private ulong timestamp;
private uint index;
private uint nonce;
private byte primaryIndex;
private UInt160 nextConsensus;


/// <summary>
/// The witness of the block.
/// </summary>
Expand Down Expand Up @@ -73,6 +75,15 @@ public uint Index
set { index = value; _hash = null; }
}

/// <summary>
/// The last four bytes of random number generated from VRF
/// </summary>
public uint Nonce
{
get => nonce;
set { nonce = value; _hash = null; }
}

/// <summary>
/// The primary index of the consensus node that generated this block.
/// </summary>
Expand Down Expand Up @@ -110,6 +121,7 @@ public UInt256 Hash
UInt256.Length + // MerkleRoot
sizeof(ulong) + // Timestamp
sizeof(uint) + // Index
sizeof(uint) + // Nonce
sizeof(byte) + // PrimaryIndex
UInt160.Length + // NextConsensus
1 + Witness.Size; // Witness
Expand Down Expand Up @@ -144,6 +156,7 @@ void IVerifiable.DeserializeUnsigned(BinaryReader reader)
merkleRoot = reader.ReadSerializable<UInt256>();
timestamp = reader.ReadUInt64();
index = reader.ReadUInt32();
nonce = reader.ReadUInt32();
primaryIndex = reader.ReadByte();
nextConsensus = reader.ReadSerializable<UInt160>();
}
Expand Down Expand Up @@ -186,6 +199,7 @@ void IVerifiable.SerializeUnsigned(BinaryWriter writer)
writer.Write(merkleRoot);
writer.Write(timestamp);
writer.Write(index);
writer.Write(nonce);
writer.Write(primaryIndex);
writer.Write(nextConsensus);
}
Expand All @@ -205,6 +219,7 @@ public JObject ToJson(ProtocolSettings settings)
json["merkleroot"] = merkleRoot.ToString();
json["time"] = timestamp;
json["index"] = index;
json["nonce"] = nonce;
json["primary"] = primaryIndex;
json["nextconsensus"] = nextConsensus.ToAddress(settings.AddressVersion);
json["witnesses"] = new JArray(Witness.ToJson());
Expand Down
18 changes: 18 additions & 0 deletions src/neo/SmartContract/ApplicationEngine.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ partial class ApplicationEngine
/// </summary>
public static readonly InteropDescriptor System_Runtime_GetInvocationCounter = Register("System.Runtime.GetInvocationCounter", nameof(GetInvocationCounter), 1 << 4, CallFlags.None);

/// <summary>
/// The <see cref="InteropDescriptor"/> of System.Runtime.GetRandom.
/// Gets the random number generated form the VRF.
/// </summary>
public static readonly InteropDescriptor System_Runtime_GetRandom = Register("System.Runtime.GetRandom", nameof(GetRandom), 1 << 4, CallFlags.None);


/// <summary>
/// The <see cref="InteropDescriptor"/> of System.Runtime.Log.
/// Writes a log.
Expand Down Expand Up @@ -228,6 +235,17 @@ protected internal int GetInvocationCounter()
return counter;
}

/// <summary>
/// The implementation of System.Runtime.GetRandom.
/// Gets the random number genrated form the VRF
/// Primary geterates this random number with `prevHash`, the hash of the previous (validators.Length/3 + 1) block
/// </summary>
/// <returns>The last four bytes of the random number.</returns>
protected internal uint GetRandom()
{
return PersistingBlock.Header.Nonce;
}

/// <summary>
/// The implementation of System.Runtime.Log.
/// Writes a log.
Expand Down
22 changes: 22 additions & 0 deletions src/neo/SmartContract/Native/StdLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,28 @@ public static byte[] Base58Decode([MaxLength(MaxInputLength)] string s)
return Base58.Decode(s);
}

/// <summary>
/// Converts a byte array to its equivalent <see cref="string"/> representation that is encoded with base-58 digits. The encoded <see cref="string"/> contains the checksum of the binary data.
/// </summary>
/// <param name="data">The byte array to be encoded.</param>
/// <returns>The encoded <see cref="string"/>.</returns>
[ContractMethod(CpuFee = 1 << 16)]
public static string Base58CheckEncode([MaxLength(MaxInputLength)] byte[] data)
{
return Base58.Base58CheckEncode(data);
}

/// <summary>
/// Converts the specified <see cref="string"/>, which encodes binary data as base-58 digits, to an equivalent byte array. The encoded <see cref="string"/> contains the checksum of the binary data.
/// </summary>
/// <param name="s">The base58 <see cref="string"/>.</param>
/// <returns>The decoded byte array.</returns>
[ContractMethod(CpuFee = 1 << 16)]
public static byte[] Base58CheckDecode([MaxLength(MaxInputLength)] string s)
{
return Base58.Base58CheckDecode(s);
}

[ContractMethod(CpuFee = 1 << 5)]
private static int MemoryCompare([MaxLength(MaxInputLength)] byte[] str1, [MaxLength(MaxInputLength)] byte[] str2)
{
Expand Down
Loading