Anatomy of smart contracts | ethereum.org (2024)

A smart contract is a program that runs at an address on Ethereum. They're made up of data and functions that can execute upon receiving a transaction. Here's an overview of what makes up a smart contract.

Make sure you've read about smart contracts first. This document assumes you're already familiar with programming languages such as JavaScript or Python.

Any contract data must be assigned to a location: either to storage or memory. It's costly to modify storage in a smart contract so you need to consider where your data should live.

Persistent data is referred to as storage and is represented by state variables. These values get stored permanently on the blockchain. You need to declare the type so that the contract can keep track of how much storage on the blockchain it needs when it compiles.

1

// Solidity example

2contract SimpleStorage {

3 uint storedData; // State variable

4 // ...

5}

Copy

1# Vyper example

2storedData: int128

Copy

If you've already programmed object-oriented languages, you'll likely be familiar with most types. However address should be new to you if you're new to Ethereum development.

An address type can hold an Ethereum address which equates to 20 bytes or 160 bits. It returns in hexadecimal notation with a leading 0x.

Values that are only stored for the lifetime of a contract function's execution are called memory variables. Since these are not stored permanently on the blockchain, they are much cheaper to use.

In addition to the variables you define on your contract, there are some special global variables. They are primarily used to provide information about the blockchain or current transaction.

In the most simplistic terms, functions can get information or set information in response to incoming transactions.

1// Solidity example

2function update_name(string value) public {

3 dapp_name = value;

4}

Copy

These functions promise not to modify the state of the contract's data. Common examples are "getter" functions – you might use this to receive a user's balance for example.

1// Solidity example

2function balanceOf(address _owner) public view returns (uint256 _balance) {

3 return ownerPizzaCount[_owner];

4}

Copy

1dappName: public(string)

2

3@view

4@public

5def readName() -> string:

6 return dappName

Copy

constructor functions are only executed once when the contract is first deployed. Like constructor in many class-based programming languages, these functions often initialize state variables to their specified values.

1// Solidity example

2// Initializes the contract's data, setting the `owner`

3// to the address of the contract creator.

4constructor() public {

5 // All smart contracts rely on external transactions to trigger its functions.

6 // `msg` is a global variable that includes relevant data on the given transaction,

7 // such as the address of the sender and the ETH value included in the transaction.

8 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties

9 owner = msg.sender;

10}

Show all

Copy

1# Vyper example

2

3@external

4def __init__(_beneficiary: address, _bidding_time: uint256):

5 self.beneficiary = _beneficiary

6 self.auctionStart = block.timestamp

7 self.auctionEnd = self.auctionStart + _bidding_time

Copy

In addition to the variables and functions you define on your contract, there are some special built-in functions. The most obvious example is:

These allow contracts to send ETH to other accounts.

1pragma solidity >=0.4.0 <=0.6.0;

2

3contract ExampleDapp {

4 string dapp_name; // state variable

5

6 // Called when the contract is deployed and initializes the value

7 constructor() public {

8 dapp_name = "My Example dapp";

9 }

10

11 // Get Function

12 function read_name() public view returns(string) {

13 return dapp_name;

14 }

15

16 // Set Function

17 function update_name(string value) public {

18 dapp_name = value;

19 }

20}

Show all

Copy

A complete contract might look something like this. Here the constructor function provides an initial value for the dapp_name variable.

Events enable your smart contract to communicate with your frontend or other subscribing applications. Once a transaction is validated and added to a block, smart contracts can emit events and log information, which the frontend can then process and utilize.

These are some examples written in Solidity. If you'd like to play with the code, you can interact with them in Remix(opens in a new tab).

1// Specifies the version of Solidity, using semantic versioning.

2// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma

3pragma solidity ^0.5.10;

4

5// Defines a contract named `HelloWorld`.

6// A contract is a collection of functions and data (its state).

7// Once deployed, a contract resides at a specific address on the Ethereum blockchain.

8// Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html

9contract HelloWorld {

10

11 // Declares a state variable `message` of type `string`.

12 // State variables are variables whose values are permanently stored in contract storage.

13 // The keyword `public` makes variables accessible from outside a contract

14 // and creates a function that other contracts or clients can call to access the value.

15 string public message;

16

17 // Similar to many class-based object-oriented languages, a constructor is

18 // a special function that is only executed upon contract creation.

19 // Constructors are used to initialize the contract's data.

20 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors

21 constructor(string memory initMessage) public {

22 // Accepts a string argument `initMessage` and sets the value

23 // into the contract's `message` storage variable).

24 message = initMessage;

25 }

26

27 // A public function that accepts a string argument

28 // and updates the `message` storage variable.

29 function update(string memory newMessage) public {

30 message = newMessage;

31 }

32}

Show all

Copy

1pragma solidity ^0.5.10;

2

3contract Token {

4 // An `address` is comparable to an email address - it's used to identify an account on Ethereum.

5 // Addresses can represent a smart contract or an external (user) accounts.

6 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/types.html#address

7 address public owner;

8

9 // A `mapping` is essentially a hash table data structure.

10 // This `mapping` assigns an unsigned integer (the token balance) to an address (the token holder).

11 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/types.html#mapping-types

12 mapping (address => uint) public balances;

13

14 // Events allow for logging of activity on the blockchain.

15 // Ethereum clients can listen for events in order to react to contract state changes.

16 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#events

17 event Transfer(address from, address to, uint amount);

18

19 // Initializes the contract's data, setting the `owner`

20 // to the address of the contract creator.

21 constructor() public {

22 // All smart contracts rely on external transactions to trigger its functions.

23 // `msg` is a global variable that includes relevant data on the given transaction,

24 // such as the address of the sender and the ETH value included in the transaction.

25 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties

26 owner = msg.sender;

27 }

28

29 // Creates an amount of new tokens and sends them to an address.

30 function mint(address receiver, uint amount) public {

31 // `require` is a control structure used to enforce certain conditions.

32 // If a `require` statement evaluates to `false`, an exception is triggered,

33 // which reverts all changes made to the state during the current call.

34 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions

35

36 // Only the contract owner can call this function

37 require(msg.sender == owner, "You are not the owner.");

38

39 // Enforces a maximum amount of tokens

40 require(amount < 1e60, "Maximum issuance exceeded");

41

42 // Increases the balance of `receiver` by `amount`

43 balances[receiver] += amount;

44 }

45

46 // Sends an amount of existing tokens from any caller to an address.

47 function transfer(address receiver, uint amount) public {

48 // The sender must have enough tokens to send

49 require(amount <= balances[msg.sender], "Insufficient balance.");

50

51 // Adjusts token balances of the two addresses

52 balances[msg.sender] -= amount;

53 balances[receiver] += amount;

54

55 // Emits the event defined earlier

56 emit Transfer(msg.sender, receiver, amount);

57 }

58}

Show all

Copy

1pragma solidity ^0.5.10;

2

3// Imports symbols from other files into the current contract.

4// In this case, a series of helper contracts from OpenZeppelin.

5// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#importing-other-source-files

6

7import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";

8import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";

9import "../node_modules/@openzeppelin/contracts/introspection/ERC165.sol";

10import "../node_modules/@openzeppelin/contracts/math/SafeMath.sol";

11

12// The `is` keyword is used to inherit functions and keywords from external contracts.

13// In this case, `CryptoPizza` inherits from the `IERC721` and `ERC165` contracts.

14// Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance

15contract CryptoPizza is IERC721, ERC165 {

16 // Uses OpenZeppelin's SafeMath library to perform arithmetic operations safely.

17 // Learn more: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath

18 using SafeMath for uint256;

19

20 // Constant state variables in Solidity are similar to other languages

21 // but you must assign from an expression which is constant at compile time.

22 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constant-state-variables

23 uint256 constant dnaDigits = 10;

24 uint256 constant dnaModulus = 10 ** dnaDigits;

25 bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

26

27 // Struct types let you define your own type

28 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs

29 struct Pizza {

30 string name;

31 uint256 dna;

32 }

33

34 // Creates an empty array of Pizza structs

35 Pizza[] public pizzas;

36

37 // Mapping from pizza ID to its owner's address

38 mapping(uint256 => address) public pizzaToOwner;

39

40 // Mapping from owner's address to number of owned token

41 mapping(address => uint256) public ownerPizzaCount;

42

43 // Mapping from token ID to approved address

44 mapping(uint256 => address) pizzaApprovals;

45

46 // You can nest mappings, this example maps owner to operator approvals

47 mapping(address => mapping(address => bool)) private operatorApprovals;

48

49 // Internal function to create a random Pizza from string (name) and DNA

50 function _createPizza(string memory _name, uint256 _dna)

51 // The `internal` keyword means this function is only visible

52 // within this contract and contracts that derive this contract

53 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters

54 internal

55 // `isUnique` is a function modifier that checks if the pizza already exists

56 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers

57 isUnique(_name, _dna)

58 {

59 // Adds Pizza to array of Pizzas and get id

60 uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1);

61

62 // Checks that Pizza owner is the same as current user

63 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions

64

65 // note that address(0) is the zero address,

66 // indicating that pizza[id] is not yet allocated to a particular user.

67

68 assert(pizzaToOwner[id] == address(0));

69

70 // Maps the Pizza to the owner

71 pizzaToOwner[id] = msg.sender;

72 ownerPizzaCount[msg.sender] = SafeMath.add(

73 ownerPizzaCount[msg.sender],

74 1

75 );

76 }

77

78 // Creates a random Pizza from string (name)

79 function createRandomPizza(string memory _name) public {

80 uint256 randDna = generateRandomDna(_name, msg.sender);

81 _createPizza(_name, randDna);

82 }

83

84 // Generates random DNA from string (name) and address of the owner (creator)

85 function generateRandomDna(string memory _str, address _owner)

86 public

87 // Functions marked as `pure` promise not to read from or modify the state

88 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions

89 pure

90 returns (uint256)

91 {

92 // Generates random uint from string (name) + address (owner)

93 uint256 rand = uint256(keccak256(abi.encodePacked(_str))) +

94 uint256(_owner);

95 rand = rand % dnaModulus;

96 return rand;

97 }

98

99 // Returns array of Pizzas found by owner

100 function getPizzasByOwner(address _owner)

101 public

102 // Functions marked as `view` promise not to modify state

103 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions

104 view

105 returns (uint256[] memory)

106 {

107 // Uses the `memory` storage location to store values only for the

108 // lifecycle of this function call.

109 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/introduction-to-smart-contracts.html#storage-memory-and-the-stack

110 uint256[] memory result = new uint256[](ownerPizzaCount[_owner]);

111 uint256 counter = 0;

112 for (uint256 i = 0; i < pizzas.length; i++) {

113 if (pizzaToOwner[i] == _owner) {

114 result[counter] = i;

115 counter++;

116 }

117 }

118 return result;

119 }

120

121 // Transfers Pizza and ownership to other address

122 function transferFrom(address _from, address _to, uint256 _pizzaId) public {

123 require(_from != address(0) && _to != address(0), "Invalid address.");

124 require(_exists(_pizzaId), "Pizza does not exist.");

125 require(_from != _to, "Cannot transfer to the same address.");

126 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");

127

128 ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1);

129 ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1);

130 pizzaToOwner[_pizzaId] = _to;

131

132 // Emits event defined in the imported IERC721 contract

133 emit Transfer(_from, _to, _pizzaId);

134 _clearApproval(_to, _pizzaId);

135 }

136

137 /**

138 * Safely transfers the ownership of a given token ID to another address

139 * If the target address is a contract, it must implement `onERC721Received`,

140 * which is called upon a safe transfer, and return the magic value

141 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;

142 * otherwise, the transfer is reverted.

143 */

144 function safeTransferFrom(address from, address to, uint256 pizzaId)

145 public

146 {

147 // solium-disable-next-line arg-overflow

148 this.safeTransferFrom(from, to, pizzaId, "");

149 }

150

151 /**

152 * Safely transfers the ownership of a given token ID to another address

153 * If the target address is a contract, it must implement `onERC721Received`,

154 * which is called upon a safe transfer, and return the magic value

155 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;

156 * otherwise, the transfer is reverted.

157 */

158 function safeTransferFrom(

159 address from,

160 address to,

161 uint256 pizzaId,

162 bytes memory _data

163 ) public {

164 this.transferFrom(from, to, pizzaId);

165 require(_checkOnERC721Received(from, to, pizzaId, _data), "Must implement onERC721Received.");

166 }

167

168 /**

169 * Internal function to invoke `onERC721Received` on a target address

170 * The call is not executed if the target address is not a contract

171 */

172 function _checkOnERC721Received(

173 address from,

174 address to,

175 uint256 pizzaId,

176 bytes memory _data

177 ) internal returns (bool) {

178 if (!isContract(to)) {

179 return true;

180 }

181

182 bytes4 retval = IERC721Receiver(to).onERC721Received(

183 msg.sender,

184 from,

185 pizzaId,

186 _data

187 );

188 return (retval == _ERC721_RECEIVED);

189 }

190

191 // Burns a Pizza - destroys Token completely

192 // The `external` function modifier means this function is

193 // part of the contract interface and other contracts can call it

194 function burn(uint256 _pizzaId) external {

195 require(msg.sender != address(0), "Invalid address.");

196 require(_exists(_pizzaId), "Pizza does not exist.");

197 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");

198

199 ownerPizzaCount[msg.sender] = SafeMath.sub(

200 ownerPizzaCount[msg.sender],

201 1

202 );

203 pizzaToOwner[_pizzaId] = address(0);

204 }

205

206 // Returns count of Pizzas by address

207 function balanceOf(address _owner) public view returns (uint256 _balance) {

208 return ownerPizzaCount[_owner];

209 }

210

211 // Returns owner of the Pizza found by id

212 function ownerOf(uint256 _pizzaId) public view returns (address _owner) {

213 address owner = pizzaToOwner[_pizzaId];

214 require(owner != address(0), "Invalid Pizza ID.");

215 return owner;

216 }

217

218 // Approves other address to transfer ownership of Pizza

219 function approve(address _to, uint256 _pizzaId) public {

220 require(msg.sender == pizzaToOwner[_pizzaId], "Must be the Pizza owner.");

221 pizzaApprovals[_pizzaId] = _to;

222 emit Approval(msg.sender, _to, _pizzaId);

223 }

224

225 // Returns approved address for specific Pizza

226 function getApproved(uint256 _pizzaId)

227 public

228 view

229 returns (address operator)

230 {

231 require(_exists(_pizzaId), "Pizza does not exist.");

232 return pizzaApprovals[_pizzaId];

233 }

234

235 /**

236 * Private function to clear current approval of a given token ID

237 * Reverts if the given address is not indeed the owner of the token

238 */

239 function _clearApproval(address owner, uint256 _pizzaId) private {

240 require(pizzaToOwner[_pizzaId] == owner, "Must be pizza owner.");

241 require(_exists(_pizzaId), "Pizza does not exist.");

242 if (pizzaApprovals[_pizzaId] != address(0)) {

243 pizzaApprovals[_pizzaId] = address(0);

244 }

245 }

246

247 /*

248 * Sets or unsets the approval of a given operator

249 * An operator is allowed to transfer all tokens of the sender on their behalf

250 */

251 function setApprovalForAll(address to, bool approved) public {

252 require(to != msg.sender, "Cannot approve own address");

253 operatorApprovals[msg.sender][to] = approved;

254 emit ApprovalForAll(msg.sender, to, approved);

255 }

256

257 // Tells whether an operator is approved by a given owner

258 function isApprovedForAll(address owner, address operator)

259 public

260 view

261 returns (bool)

262 {

263 return operatorApprovals[owner][operator];

264 }

265

266 // Takes ownership of Pizza - only for approved users

267 function takeOwnership(uint256 _pizzaId) public {

268 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");

269 address owner = this.ownerOf(_pizzaId);

270 this.transferFrom(owner, msg.sender, _pizzaId);

271 }

272

273 // Checks if Pizza exists

274 function _exists(uint256 pizzaId) internal view returns (bool) {

275 address owner = pizzaToOwner[pizzaId];

276 return owner != address(0);

277 }

278

279 // Checks if address is owner or is approved to transfer Pizza

280 function _isApprovedOrOwner(address spender, uint256 pizzaId)

281 internal

282 view

283 returns (bool)

284 {

285 address owner = pizzaToOwner[pizzaId];

286 // Disable solium check because of

287 // https://github.com/duaraghav8/Solium/issues/175

288 // solium-disable-next-line operator-whitespace

289 return (spender == owner ||

290 this.getApproved(pizzaId) == spender ||

291 this.isApprovedForAll(owner, spender));

292 }

293

294 // Check if Pizza is unique and doesn't exist yet

295 modifier isUnique(string memory _name, uint256 _dna) {

296 bool result = true;

297 for (uint256 i = 0; i < pizzas.length; i++) {

298 if (

299 keccak256(abi.encodePacked(pizzas[i].name)) ==

300 keccak256(abi.encodePacked(_name)) &&

301 pizzas[i].dna == _dna

302 ) {

303 result = false;

304 }

305 }

306 require(result, "Pizza with such name already exists.");

307 _;

308 }

309

310 // Returns whether the target address is a contract

311 function isContract(address account) internal view returns (bool) {

312 uint256 size;

313 // Currently there is no better way to check if there is a contract in an address

314 // than to check the size of the code at that address.

315 // See https://ethereum.stackexchange.com/a/14016/36603

316 // for more details about how this works.

317 // TODO Check this again before the Serenity release, because all addresses will be

318 // contracts then.

319 // solium-disable-next-line security/no-inline-assembly

320 assembly {

321 size := extcodesize(account)

322 }

323 return size > 0;

324 }

325}

Show all

Copy

Check out Solidity and Vyper's documentation for a more complete overview of smart contracts:

Anatomy of smart contracts | ethereum.org (2024)

FAQs

What is the anatomy of smart contracts? ›

Smart contracts are programs that are immutably stored in the chain. Through VM abstraction, the ISC virtual machine is agnostic about the interpreter used to execute each smart contract. It can support different VM types (i.e., interpreters) simultaneously on the same chain.

What are the four major parts of a smart contract? ›

What Are the Four Major Parts of a Smart Contract? It depends on the blockchain and how it is programmed. Generally speaking, smart contracts have state variables (data), functions (what can be done), events (messages in and out), and modifiers (special rules for specific users).

What is smart contract answer? ›

Smart contracts are typically used to automate the execution of an agreement so that all participants can be immediately certain of the outcome, without any intermediary's involvement or time loss. They can also automate a workflow, triggering the next action when predetermined conditions are met.

Are smart contracts hard to write? ›

If you have no experience, it may take you a few months to get comfortable with coding a simple smart contract. Developers with more experience might need just days or weeks.

What is the structure of a smart contract? ›

A smart contract's structure can vary depending on its purpose, but most smart contracts follow a similar structure: Preamble: This section includes basic information about the contract, such as the contract's name and version. State Variables: These are the variables that store the contract's state.

What are the top 10 smart contracts? ›

The top 10 best smart contract platforms in 2024 are Ethereum, Binance Smart Chain (BSC), TRON, Arbitrum, Cardano, Solana, Polygon, Algorand, Avalanche, and Tezos.

What is the architecture of smart contracts? ›

Smart contracts are stored on the blockchain, which is a network of computers/servers connected to each other and governed by a protocol. This level of decentralization ensures security and prevents censorship.

What are the 4 main elements of a contract? ›

The basic elements required for the agreement to be a legally enforceable contract are: mutual assent, expressed by a valid offer and acceptance; adequate consideration; capacity; and legality.

What are the main features of smart contracts? ›

Deterministic: smart contracts can only perform their intended functions when the required conditions are met. The end result will be the same regardless of who executes the smart contract. Immutable: once deployed, a smart contract cannot be changed. Autonomy: no third parties are involved.

What are the basics of smart contracts? ›

A Smart Contract (or cryptocontract) is a computer program that directly and automatically controls the transfer of digital assets between the parties under certain conditions. A smart contract works in the same way as a traditional contract while also automatically enforcing the contract.

Are smart contracts really smart? ›

The idea behind smart contracts is to automate the execution of agreements, cutting out the need for intermediaries such as lawyers, notaries, or banks. This automation is expected to reduce costs and minimise the potential for human error, making transactions more efficient and trustworthy.

What is a real example of smart contract? ›

A smart contract is a self-executing program based on if-then logic. Vending machines provide a good analogy. If someone inserts $2 and presses B4, then the machine dispenses the cookies in the B4 slot. In other words, if the vending machine receives the required item of value, then it performs the requested action.

Can AI write smart contracts? ›

For example, in the insurance industry, AI-coded smart contracts can assess risk factors and adjust premium rates in real-time. Natural Language Processing (NLP): NLP, a subset of AI, can be used to translate complex legal documents into code.

What is a drawback of smart contracts? ›

Disadvantages of Smart Contracts :-

It is resistant to the modification of the data. For example – If you want to buy a new car, then data already stored can't be changed so easily. This makes the data less secure in its use and more prone to securities issues.

What is a criticism of smart contracts? ›

Risks of Smart Contract

Paradoxically, the principal weakness of smart contracts lies in one of their greatest strengths: certainty of execution. Even if both parties wish to prevent the execution of their smart contract, they are condemned to suffer its execution.

What are the parameters of a smart contract? ›

Parameters are the variables that control the behavior and logic of your smart contract, such as fees, rates, limits, or thresholds. You should document your parameters in a separate file or repository, using a standard format, such as JSON or YAML.

What are the smart contract phases? ›

These four phases are the formation of a smart contract, freezing of the smart contract, execution of the smart contract, and finalization of the smart contract.

Top Articles
Report: Small businesses are failing at higher rates in their first year
Read This Before Choosing Satin vs. Eggshell Paint
Zabor Funeral Home Inc
Gomoviesmalayalam
Wordscapes Level 5130 Answers
Google Jobs Denver
Craigslist Kennewick Pasco Richland
How To Get Free Credits On Smartjailmail
Here's how eating according to your blood type could help you keep healthy
About Goodwill – Goodwill NY/NJ
Acbl Homeport
Boat Jumping Female Otezla Commercial Actress
What is a basic financial statement?
fltimes.com | Finger Lakes Times
Washington Poe en Tilly Bradshaw 1 - Brandoffer, M.W. Craven | 9789024594917 | Boeken | bol
Arre St Wv Srj
Adam4Adam Discount Codes
Craigslist Free Stuff Merced Ca
Talbots.dayforce.com
Recap: Noah Syndergaard earns his first L.A. win as Dodgers sweep Cardinals
Kringloopwinkel Second Sale Roosendaal - Leemstraat 4e
Heart Ring Worth Aj
Gran Turismo Showtimes Near Marcus Renaissance Cinema
LCS Saturday: Both Phillies and Astros one game from World Series
PCM.daily - Discussion Forum: Classique du Grand Duché
Danielle Ranslow Obituary
Ardie From Something Was Wrong Podcast
Valley Craigslist
APUSH Unit 6 Practice DBQ Prompt Answers & Feedback | AP US History Class Notes | Fiveable
Kltv Com Big Red Box
Craigslist Ludington Michigan
1-800-308-1977
Greater Keene Men's Softball
Arcadia Lesson Plan | Day 4: Crossword Puzzle | GradeSaver
Rhode Island High School Sports News & Headlines| Providence Journal
Academy Sports New Bern Nc Coupons
California Craigslist Cars For Sale By Owner
Anthem Bcbs Otc Catalog 2022
Guided Practice Activities 5B-1 Answers
The Nikki Catsouras death - HERE the incredible photos | Horror Galore
Europa Universalis 4: Army Composition Guide
How to Find Mugshots: 11 Steps (with Pictures) - wikiHow
About us | DELTA Fiber
Is TinyZone TV Safe?
Uncle Pete's Wheeling Wv Menu
Craigslist Monterrey Ca
Phumikhmer 2022
Ihop Deliver
Scholar Dollar Nmsu
Latest Posts
Article information

Author: Tuan Roob DDS

Last Updated:

Views: 5989

Rating: 4.1 / 5 (62 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Tuan Roob DDS

Birthday: 1999-11-20

Address: Suite 592 642 Pfannerstill Island, South Keila, LA 74970-3076

Phone: +9617721773649

Job: Marketing Producer

Hobby: Skydiving, Flag Football, Knitting, Running, Lego building, Hunting, Juggling

Introduction: My name is Tuan Roob DDS, I am a friendly, good, energetic, faithful, fantastic, gentle, enchanting person who loves writing and wants to share my knowledge and understanding with you.