> ## Documentation Index
> Fetch the complete documentation index at: https://docs.near.org/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK Types

> Learn everything the SDK has to offer to efficiently store data.

export const File = ({children}) => {
  return children;
};

export const Block = ({children}) => {
  return children;
};

export const ExplainCode = ({children, languages}) => {
  const langList = typeof languages === 'string' ? languages.split(',') : languages || [];
  const [language, setLanguage] = useState(langList[0]);
  const [activeBlock, setActiveBlock] = useState(0);
  const [code, setCode] = useState(null);
  const blockRefs = useRef({});
  const codeContainerRef = useRef(null);
  const ratioMap = useRef({});
  const lang2label = {
    rust: '🦀 Rust',
    js: '🌐 JS',
    ts: '🌐 TS',
    python: '🐍 Python',
    go: '🐹 Go'
  };
  const typeAccentClass = {
    state: 'border-l-4 border-emerald-500',
    warning: 'border-l-4 border-amber-500',
    note: 'border-l-4 border-amber-500'
  };
  const accentBorder = t => typeAccentClass[t] || 'border-l-4 border-indigo-500';
  function toRaw(ref) {
    const fullUrl = ref.slice(ref.indexOf('https'));
    const [url] = fullUrl.split('#');
    const [org, repo, , branch, ...pathSeg] = new URL(url).pathname.split('/').slice(1);
    return `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${pathSeg.join('/')}`;
  }
  async function fetchRaw(url, fromLine, toLine) {
    let res;
    if (typeof window !== 'undefined') {
      const validUntil = localStorage.getItem(`${url}-until`);
      if (validUntil && Number(validUntil) > Date.now()) {
        res = localStorage.getItem(url);
      }
    }
    if (!res) {
      try {
        res = await (await fetch(url)).text();
        if (typeof window !== 'undefined') {
          localStorage.setItem(url, res);
          localStorage.setItem(`${url}-until`, String(Date.now() + 60000));
        }
      } catch {
        return 'Error fetching code, please try reloading';
      }
    }
    let lines = res.split('\n');
    const from = fromLine ? Number(fromLine) - 1 : 0;
    const to = toLine ? Number(toLine) : lines.length;
    lines = lines.slice(from, to);
    const indent = lines.reduce((prev, line) => {
      if (!line.length) return prev;
      const m = line.match(/^\s+/);
      return m ? Math.min(prev, m[0].length) : 0;
    }, Infinity);
    return lines.map(l => l.slice(indent === Infinity ? 0 : indent)).join('\n');
  }
  function parseHighlights(str) {
    const set = new Set();
    if (!str) return set;
    String(str).split(',').forEach(part => {
      const [a, b] = part.trim().split('-');
      if (b) {
        for (let i = Number(a); i <= Number(b); i++) set.add(i);
      } else if (a) set.add(Number(a));
    });
    return set;
  }
  const childArray = Array.isArray(children) ? children.flat(Infinity) : children ? [children] : [];
  const blocks = [];
  const files = [];
  for (const child of childArray) {
    if (!child || typeof child !== 'object' || !child.props) continue;
    if (child.props.highlights !== undefined) {
      let hl = {};
      try {
        hl = JSON.parse(child.props.highlights);
      } catch {}
      if ((language in hl)) {
        blocks.push({
          text: child.props.children,
          highlight: hl[language],
          fname: child.props.fname,
          type: child.props.type
        });
      }
    } else if (child.props.language === language) {
      files.push({
        ...child.props
      });
    }
  }
  const activeFname = blocks[activeBlock]?.fname || files[0]?.fname;
  const fileKey = `${activeFname}-${language}`;
  const currentFile = files.find(f => f.fname === activeFname) || files[0];
  useEffect(() => {
    setActiveBlock(0);
    setCode(null);
    ratioMap.current = {};
  }, [language]);
  useEffect(() => {
    const observedEls = Object.entries(blockRefs.current).filter(([, el]) => el);
    const observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        const idx = Number(entry.target.dataset.blockIdx);
        ratioMap.current[idx] = entry.intersectionRatio;
      });
      let bestIdx = -1;
      let bestRatio = 0;
      Object.entries(ratioMap.current).forEach(([idx, ratio]) => {
        if (ratio > bestRatio) {
          bestRatio = ratio;
          bestIdx = Number(idx);
        }
      });
      if (bestIdx !== -1) {
        setActiveBlock(bestIdx);
      } else {
        const zoneTop = window.innerHeight * 0.2;
        const allAboveZone = Object.entries(blockRefs.current).filter(([, el]) => el).every(([, el]) => el.getBoundingClientRect().bottom < zoneTop);
        if (allAboveZone) setActiveBlock(-1);
      }
    }, {
      threshold: [0, 0.1, 0.25, 0.5, 0.75, 1],
      rootMargin: '-20% 0px -50% 0px'
    });
    observedEls.forEach(([idx, el]) => {
      el.dataset.blockIdx = idx;
      observer.observe(el);
    });
    return () => observer.disconnect();
  }, [blocks.length]);
  useEffect(() => {
    const container = codeContainerRef.current;
    if (!container) return;
    const firstHL = container.querySelector('[data-first-hl]');
    if (!firstHL) return;
    const targetScrollTop = container.scrollTop + firstHL.getBoundingClientRect().top - container.getBoundingClientRect().top - container.clientHeight / 2 + firstHL.offsetHeight / 2;
    container.scrollTo({
      top: Math.max(0, targetScrollTop),
      behavior: 'smooth'
    });
  }, [activeBlock]);
  useEffect(() => {
    if (!currentFile?.url) return;
    setCode(null);
    const rawUrl = toRaw(currentFile.url);
    fetchRaw(rawUrl, currentFile.start, currentFile.end).then(setCode);
  }, [fileKey]);
  const startLine = currentFile?.start ? Number(currentFile.start) : 1;
  const highlighted = parseHighlights(blocks[activeBlock]?.highlight);
  const firstHlLine = highlighted.size > 0 ? Math.min(...highlighted) : -1;
  return <div className="my-6 not-prose">
      {}
      <div className="flex border-b border-gray-200 dark:border-gray-700 mb-4">
        {langList.map(lang => <button key={lang} onClick={() => setLanguage(lang)} className={['px-4 py-2 text-sm font-medium bg-transparent cursor-pointer', 'border-0 border-b-2 -mb-px transition-colors outline-none', language === lang ? 'border-blue-500 text-blue-500 dark:text-blue-400 dark:border-blue-400' : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200'].join(' ')}>
            {lang2label[lang] || lang}
          </button>)}
      </div>

      {}
      <div className="flex gap-8 items-start">
        {}
        <div className="flex-[5] flex flex-col gap-3 min-w-0 pb-[40vh]">
          {blocks.map((block, i) => <div key={i} ref={el => {
    blockRefs.current[i] = el;
  }} onClick={() => !block.type && setActiveBlock(i)} className={['px-5 py-4 rounded-md transition-all duration-200', block.type ? `cursor-default ${accentBorder(block.type)} opacity-75` : activeBlock === i ? `cursor-pointer ${accentBorder(block.type)} shadow-sm` : `cursor-pointer ${accentBorder(block.type)} opacity-60 hover:opacity-90`].join(' ')} style={{
    backgroundColor: block.type ? 'var(--explain-card-bg)' : activeBlock === i ? 'var(--explain-card-active-bg)' : 'var(--explain-card-bg)',
    border: !block.type && activeBlock === i ? '1px solid var(--explain-card-border)' : '1px solid transparent'
  }}>
              {block.text}
            </div>)}
        </div>

        {}
        {currentFile && <div className="flex-[6] min-w-0 rounded-[10px] border border-[#d0d7de] dark:border-[#30363d] overflow-hidden sticky top-6 max-h-[calc(100vh-5rem)] flex flex-col shadow-md bg-white dark:bg-[#0d1117]">
            {}
            <div className="flex items-center justify-between px-[14px] py-2 bg-[#f6f8fa] dark:bg-[#161b22] border-b border-[#d0d7de] dark:border-[#30363d] shrink-0">
              <div className="flex items-center gap-2">
                <svg width="14" height="14" viewBox="0 0 24 24" className="fill-[#657279] dark:fill-[#8b949e]">
                  <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z" />
                </svg>
                <span className="text-[0.8125rem] font-medium text-[#1f2328] dark:text-[#e6edf3]">{currentFile.fname}</span>
              </div>
              <a href={`${currentFile.url}#L${currentFile.start}-L${currentFile.end}`} target="_blank" rel="noreferrer noopener" className="text-[0.6875rem] no-underline flex items-center gap-1 transition-colors text-[#656d76] dark:text-[#8b949e] hover:text-[#1f2328] dark:hover:text-[#e6edf3]">
                View on GitHub
                <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
                  <polyline points="15 3 21 3 21 9" />
                  <line x1="10" y1="14" x2="21" y2="3" />
                </svg>
              </a>
            </div>

            {}
            <div className="overflow-auto flex-1" ref={codeContainerRef}>
              {code === null ? <div className="p-4 text-xs text-gray-500 dark:text-gray-400">Loading...</div> : <table className="w-full border-collapse font-mono text-[13px] leading-relaxed">
                  <tbody>
                    {code.split('\n').map((line, i) => {
    const lineNum = startLine + i;
    const isHL = highlighted.has(i + 1);
    return <tr key={i} {...i + 1 === firstHlLine ? {
      'data-first-hl': ''
    } : {}} style={isHL ? {
      backgroundColor: 'rgba(250,204,21,0.08)'
    } : undefined}>
                          <td style={{
      minWidth: '70px'
    }} className="py-0 pl-3 pr-3 text-right text-[0.7rem] text-[#8c959f] dark:text-gray-400 w-12 min-w-[3rem] whitespace-nowrap border-r border-[#d0d7de] dark:border-gray-700 select-none align-top">
                            {lineNum}
                          </td>
                          <td style={isHL ? {
      borderLeft: '2px solid #facc15'
    } : undefined} className="pl-4 pr-6 whitespace-pre text-[#1f2328] dark:text-[#e6edf3] align-top">
                            {line || ' '}
                          </td>
                        </tr>;
  })}
                  </tbody>
                </table>}
            </div>
          </div>}
      </div>
    </div>;
};

Lets discuss which types smart contracts use to input and output data, as well as how such data is stored and handled in the contract's code.

<ExplainCode languages="rust,js,python,go">
  <Block highlights="{&#x22;js&#x22;:&#x22;5,8,13&#x22;}" fname="hello-near">
    ### Native Types

    Smart contracts can receive, store and return data using JS native types:

    * `string`
    * `number`
    * `boolean`
    * `Array`
    * `Map`
    * `Object`
    * `BigInt`
  </Block>

  <Block highlights="{&#x22;rust&#x22;:&#x22;6,13,22,27&#x22;}" fname="hello-near">
    ### Native Types

    Smart contracts can receive, store and return data using the following Rust types:

    * `string`
    * `i8-i32/u8-u32`
    * **`u64/128`**: It is preferable to use SDK types `U64` and `U128`
    * `bool`
    * `HashMap`
    * `Vector`
  </Block>

  <Block highlights="{&#x22;python&#x22;:&#x22;11,16&#x22;}" fname="hello-near">
    ### Native Types

    Smart contracts can receive, store and return data using the following Python types:

    * `str`
    * `int`
    * `float`
    * `bool`
    * `list`
    * `dict`
    * `set`
    * `bytes`
    * `None`
  </Block>

  <Block highlights="{&#x22;go&#x22;: &#x22;13-14,25-27&#x22;}" fname="auction">
    ### Native Types

    Smart contracts can receive, store and return data using the following Go types:

    * `string`
    * `uint64`, `int64`, `float64`
    * `bool`
    * Custom structs (with `json:"..."` tags for serialization)

    **Note:** Go does not have a native 128-bit integer type. Use `types.Uint128` from the SDK to handle large token amounts.
  </Block>

  <Block highlights="{&#x22;rust&#x22;: &#x22;1,15,24,81&#x22;}" fname="auction" type="info">
    <Warning>
      **`U64/U128`**

      Smart contracts can store `u64` and `u128`, but these types need to be converted to `string` for input/output, since JSON cannot serialize values with more than 52 bits

      To simplify development, the SDK provides the `U64` and `U128` types which are automatically casted to `u64/u128` when stored, and to `string` when used as input/output
    </Warning>
  </Block>

  <Block highlights="{&#x22;python&#x22;: &#x22;26,28&#x22;}" fname="auction" type="info">
    <Tip>
      **Python Large Numbers**

      Python's `int` type has unlimited precision, so it can handle large integers (like yoctoNEAR values) without any special handling. All values are automatically serialized and deserialized correctly.
    </Tip>
  </Block>

  <Block highlights="{&#x22;go&#x22;: &#x22;50,55,72,93&#x22;}" fname="auction" type="info">
    <Warning>
      **`types.Uint128`**

      Go does not have a native 128-bit integer type. The SDK provides `types.Uint128` to handle large token amounts (e.g. yoctoNEAR values).

      Use `types.U128FromString(str)` to parse from a string, and `.String()` to convert back for output. Use `types.U64ToUint128(n)` for small constants.
    </Warning>
  </Block>

  <Block highlights="{&#x22;js&#x22;:&#x22;3-6&#x22;, &#x22;rust&#x22;: &#x22;6-9&#x22;, &#x22;python&#x22;: &#x22;10-13&#x22;, &#x22;go&#x22;: &#x22;12-15,17-20,22-28&#x22;}" fname="auction">
    ### Complex Objects

    Smart contracts can store and return complex objects

    **Note:** Objects will always be received and returned as JSON
  </Block>

  <Block highlights="{&#x22;rust&#x22;: &#x22;4&#x22;}" fname="auction">
    #### Serializers

    Objects that will be used as input or output need to be serializable to JSON, add the `#[near(serializer=json)]` macro

    Objects that will be stored in the contract's state need to be serializable to Borsh, add the `#[near(serializer=borsh)]` macro
  </Block>

  <Block highlights="{&#x22;go&#x22;: &#x22;13-14,18-19,24-27&#x22;}" fname="auction">
    #### JSON Tags

    In Go, struct fields used as input, output, or contract state must have `json:"field_name"` tags. The SDK uses these tags to serialize and deserialize data automatically.
  </Block>

  <Block highlights="{&#x22;python&#x22;: &#x22;7,14,17,20&#x22;}" fname="auction">
    #### Serialization

    Python objects are automatically serialized and deserialized using JSON for input/output and Pickle for internal storage.

    Complex nested objects like lists and dictionaries can be used directly without additional configuration.
  </Block>

  <Block highlights="{&#x22;js&#x22;: &#x22;5,10,28&#x22;}" fname="auction">
    ### Handling Tokens

    `$NEAR` tokens are typed as `BigInt` in JS, and their values represented in `yoctonear`

    **Note:** 1 NEAR = 10^24 yoctoNEAR
  </Block>

  <Block highlights="{&#x22;rust&#x22;: &#x22;8,28,45&#x22;}" fname="auction">
    ### Handling Tokens

    `$NEAR` tokens are handled through the `NearToken` struct, which exposes methods to represent the value in `yoctonear`, `milinear` and `near`

    **Note:** 1 NEAR = 10^24 yoctonear
  </Block>

  <Block highlights="{&#x22;python&#x22;: &#x22;&#x22;}" fname="auction">
    ### Handling Tokens

    `$NEAR` tokens are represented as integers in Python, with values in `yoctoNEAR`.
    The `near_sdk_py.constants` module provides `ONE_NEAR` and `ONE_TGAS` constants.

    **Note:** 1 NEAR = 10^24 yoctoNEAR
  </Block>

  <Block highlights="{&#x22;go&#x22;: &#x22;50,55,72,93&#x22;}" fname="auction">
    ### Handling Tokens

    `$NEAR` tokens are represented as `types.Uint128` in Go, with values in `yoctoNEAR`.

    * `env.GetAttachedDeposit()` returns the attached deposit as `types.Uint128`
    * `types.U128FromString(str)` parses a token amount from string
    * `types.U64ToUint128(n)` converts a small constant to `Uint128`
    * `.String()` converts back to string for storage or output

    **Note:** 1 NEAR = 10^24 yoctoNEAR
  </Block>

  <Block highlights="{&#x22;js&#x22;: &#x22;4,29&#x22;, &#x22;rust&#x22;: &#x22;7,46&#x22;, &#x22;python&#x22;: &#x22;&#x22;, &#x22;go&#x22;: &#x22;32,64&#x22;}" fname="auction">
    ### Account

    The SDK exposes a special type to handle NEAR Accounts, which automatically checks if the account address is valid
  </Block>

  <Block highlights="{&#x22;python&#x22;: &#x22;&#x22;}" fname="auction">
    ### Account IDs

    In Python, NEAR account IDs are represented as `str` types. The SDK performs validation
    when account IDs are used in contract calls or cross-contract interactions.
  </Block>

  <Block highlights="{&#x22;go&#x22;: &#x22;32,64&#x22;}" fname="auction">
    ### Account IDs

    In Go, NEAR account IDs are represented as `string`. Functions like `env.GetPredecessorAccountID()` and `env.GetCurrentAccountId()` return account IDs as plain strings.
  </Block>

  <File language="js" fname="hello-near" url="https://github.com/near-examples/hello-near-examples/blob/main/contract-ts/src/contract.ts" start="2" end="18" />

  <File language="rust" fname="hello-near" url="https://github.com/near-examples/hello-near-examples/blob/main/contract-rs/src/lib.rs" start="2" end="32" />

  <File language="python" fname="hello-near" url="https://github.com/r-near/near-py-examples/blob/main/hello-near.py" start="2" end="18" />

  <File language="js" fname="auction" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/src/contract.ts" start="2" end="61" />

  <File language="rust" fname="auction" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/src/lib.rs" start="2" end="84" />

  <File language="python" fname="auction" url="https://github.com/r-near/near-py-examples/blob/main/auction.py" start="2" end="122" />

  <File language="go" fname="hello-near" url="https://github.com/Emir-Asanov/near-go-examples/blob/example-release-1/greeting/main.go" start="1" end="27" />

  <File language="go" fname="auction" url="https://github.com/Emir-Asanov/near-go-examples/blob/example-release-1/auction/main.go" start="1" end="121" />
</ExplainCode>
