Building with Solidity

8. Owners and Doors

Implement constructors and access‑control modifiers (onlyOwner) for secure administration.

Prerequisites

Contract Ownership & Access Control

Every dApp needs someone holding the keys to the control room. That’s the owner.​
You usually set the owner once, in the constructor, when the contract is deployed:

address private contractOwner;

constructor() {
    contractOwner = msg.sender;
}
address private contractOwner;

constructor() {
    contractOwner = msg.sender;
}
address private contractOwner;

constructor() {
    contractOwner = msg.sender;
}

Here, msg.sender is the address that deployed the contract. On VeChain, this might be your deployment script or VeWorld.​

To guard sensitive functions, you wrap them with a modifier like onlyOwner:

modifier onlyOwner() {
    require(msg.sender == contractOwner, "Only owner can call this");
    _;
}

function addUser(...) public onlyOwner {
    // admin-only logic
}
modifier onlyOwner() {
    require(msg.sender == contractOwner, "Only owner can call this");
    _;
}

function addUser(...) public onlyOwner {
    // admin-only logic
}
modifier onlyOwner() {
    require(msg.sender == contractOwner, "Only owner can call this");
    _;
}

function addUser(...) public onlyOwner {
    // admin-only logic
}

Think of a modifier like a reusable gateway: the code inside runs before the main function body.​

In the WorkshopContract, this pattern controls who can manage participants and critical settings, while regular users only call safe endpoints like checkIn.​

Common Pitfalls

Forgetting to restrict admin methods can let anyone mint, burn, or reconfigure your system.

Awesome! You now understand why ownership separation is mandatory even when VeChain gas is low and fees can be delegated.