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