rippled
Loading...
Searching...
No Matches
nft.h
1#pragma once
2
3#include <xrpl/basics/base_uint.h>
4#include <xrpl/basics/tagged_integer.h>
5#include <xrpl/protocol/AccountID.h>
6
7#include <boost/endian/conversion.hpp>
8
9#include <cstdint>
10#include <cstring>
11
12namespace xrpl {
13namespace nft {
14
15// Separate taxons from regular integers.
17{
18};
20
21inline Taxon
23{
24 return static_cast<Taxon>(i);
25}
26
27inline std::uint32_t
29{
30 return static_cast<std::uint32_t>(t);
31}
32
33constexpr std::uint16_t const flagBurnable = 0x0001;
34constexpr std::uint16_t const flagOnlyXRP = 0x0002;
35constexpr std::uint16_t const flagCreateTrustLines = 0x0004;
36constexpr std::uint16_t const flagTransferable = 0x0008;
37constexpr std::uint16_t const flagMutable = 0x0010;
38
39inline std::uint16_t
40getFlags(uint256 const& id)
41{
42 std::uint16_t flags;
43 memcpy(&flags, id.begin(), 2);
44 return boost::endian::big_to_native(flags);
45}
46
47inline std::uint16_t
49{
50 std::uint16_t fee;
51 memcpy(&fee, id.begin() + 2, 2);
52 return boost::endian::big_to_native(fee);
53}
54
55inline std::uint32_t
57{
58 std::uint32_t seq;
59 memcpy(&seq, id.begin() + 28, 4);
60 return boost::endian::big_to_native(seq);
61}
62
63inline Taxon
65{
66 // An issuer may issue several NFTs with the same taxon; to ensure that NFTs
67 // are spread across multiple pages we lightly mix the taxon up by using the
68 // sequence (which is not under the issuer's direct control) as the seed for
69 // a simple linear congruential generator.
70 //
71 // From the Hull-Dobell theorem we know that f(x)=(m*x+c) mod n will yield a
72 // permutation of [0, n) when n is a power of 2 if m is congruent to 1 mod 4
73 // and c is odd.
74 //
75 // Here we use m = 384160001 and c = 2459. The modulo is implicit because we
76 // use 2^32 for n and the arithmetic gives it to us for "free".
77 //
78 // Note that the scramble value we calculate is not cryptographically secure
79 // but that's fine since all we're looking for is some dispersion.
80 //
81 // **IMPORTANT** Changing these numbers would be a breaking change requiring
82 // an amendment along with a way to distinguish token IDs that
83 // were generated with the old code.
84 return taxon ^ toTaxon(((384160001 * tokenSeq) + 2459));
85}
86
87inline Taxon
88getTaxon(uint256 const& id)
89{
90 std::uint32_t taxon;
91 memcpy(&taxon, id.begin() + 24, 4);
92 taxon = boost::endian::big_to_native(taxon);
93
94 // The taxon cipher is just an XOR, so it is reversible by applying the
95 // XOR a second time.
96 return cipheredTaxon(getSerial(id), toTaxon(taxon));
97}
98
99inline AccountID
101{
102 return AccountID::fromVoid(id.data() + 4);
103}
104
105} // namespace nft
106} // namespace xrpl
static base_uint fromVoid(void const *data)
Definition base_uint.h:291
A type-safe wrap around standard integral types.
std::uint32_t toUInt32(Taxon t)
Definition nft.h:28
constexpr std::uint16_t const flagCreateTrustLines
Definition nft.h:35
constexpr std::uint16_t const flagOnlyXRP
Definition nft.h:34
Taxon getTaxon(uint256 const &id)
Definition nft.h:88
constexpr std::uint16_t const flagTransferable
Definition nft.h:36
Taxon toTaxon(std::uint32_t i)
Definition nft.h:22
constexpr std::uint16_t const flagBurnable
Definition nft.h:33
Taxon cipheredTaxon(std::uint32_t tokenSeq, Taxon taxon)
Definition nft.h:64
AccountID getIssuer(uint256 const &id)
Definition nft.h:100
std::uint16_t getTransferFee(uint256 const &id)
Definition nft.h:48
tagged_integer< std::uint32_t, TaxonTag > Taxon
Definition nft.h:19
std::uint32_t getSerial(uint256 const &id)
Definition nft.h:56
constexpr std::uint16_t const flagMutable
Definition nft.h:37
std::uint16_t getFlags(uint256 const &id)
Definition nft.h:40
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5